Known Limitations

Verified runtime constraints, maintainability concerns, and deployment uncertainties in the current backend.

Status: complete · Source: content/docs/known-limitations.mdx

Use this index when a contribution depends on authentication, database invariants, response contracts, or deployment behavior. Each entry describes the current implementation and links to details; it is not a fix roadmap or a severity assessment.

These limitations were checked against ElixirV4 revision 76b958a17fd864923ec7616757d7946560ef5195. Runtime behavior, maintainability concerns, and deployment uncertainty are distinguished in the descriptions. Source links follow the handbook's main-branch convention; recheck the implementation when updating or removing an entry.

Authentication & security

Token claims can outlive account changes

  • Current behavior: Seven-day JWTs carry userId, email, and role. Shared authentication verifies the token without loading the account; role middleware uses the token role. There is no application refresh/revocation route or server-side logout invalidation. /auth/me reloads a user but does not replace the JWT.
  • Impact: Role changes or account deletion do not invalidate an issued token through shared middleware. Individual controller/database checks still apply; do not assume every protected route checks current account state.
  • Further reading: JWT identity.

Sourcebackend/src/utils/jwt.ts

Sourcebackend/src/middleware/auth.ts

OAuth state checks do not validate every state field

  • Current behavior: Browser OAuth compares a state nonce with a cookie, but the callback does not sign or allowlist the state's frontend origin/destination. It only checks that the selected frontend URL is nonempty before building the redirect. The application JWT appears in the redirect query string.
  • Impact: Nonce matching does not establish the trustworthiness of the other state fields. Query-string token transport requires care around URL history and logging. These are verified trust/transport behaviors, not a claim of a demonstrated exploit or incident.
  • Further reading: Google browser OAuth.

Sourcebackend/src/controllers/authController.ts

Rate-limit keys are not verified identities

  • Current behavior: The global limiter uses userId decoded from an unverified bearer payload. Its fallback passes the request object to ipKeyGenerator rather than an IP string; Express also trusts one proxy hop.
  • Impact: Do not treat the limiter's bucket identity as authentication or assume the intended per-IP fallback works. The proxy setting needs to match hosting topology; deployed behavior and exploitability have not been established here.
  • Further reading: Request lifecycle.

Sourcebackend/src/app.ts

Data integrity

Leadership, membership, and role can diverge

  • Current behavior: Club.clubHeadId is a unique optional scalar without a foreign key. Club creation writes the club and then updates the user's role/membership in separate statements. User administration can change role or membership without synchronizing leadership.
  • Impact: The database does not enforce one leadership invariant or clear a deleted user's leadership scalar. Event ownership follows current membership, so clubHeadId alone cannot predict access; partial writes can also leave inconsistent state.
  • Further reading: Club leadership and membership, Membership and leadership.

Sourcebackend/prisma/schema.prisma

Sourcebackend/src/controllers/clubController.ts

Sourcebackend/src/controllers/userController.ts

User deletion is restricted by registrations and blogs

  • Current behavior: User deletion directly calls Prisma delete, despite a comment claiming cascades. Registration and blog foreign keys use ON DELETE RESTRICT; only mentor likes cascade. A restricted delete reaches the controller's HTTP 500 catch response.
  • Impact: Accounts with registrations or authored blogs cannot be removed through that operation. Reason from the migration constraints rather than the controller comment.
  • Further reading: Deletion behavior, Delete a user.

Sourcebackend/prisma/migrations/20250829203812_initial_migration/migration.sql

Sourcebackend/prisma/migrations/20250901211052_add_blogs/migration.sql

Event reassignment checks the existing club only

  • Current behavior: A club head updating an event must belong to its current club, but can then supply another clubId. The controller does not perform a second ownership check on the destination club; the foreign key requires that club to exist.
  • Impact: Passing the initial ownership check does not confine the update to the current club. Account for reassignment explicitly when changing event access or callers.
  • Further reading: Events belong to clubs, Update an event.

Sourcebackend/src/controllers/eventController.ts

Backend architecture

Prisma lifecycle covers only the shared client

  • Current behavior: Events, blogs, mentors, and testimonials share src/lib/prisma.ts; authentication, clubs, and users construct separate module-level clients. Local startup and SIGTERM handling connect/disconnect only the shared client; serverless wrappers do not run that lifecycle.
  • Impact: This is a connection-management and maintainability concern. Do not infer application-wide pooling or cleanup from the shared helper; no connection-exhaustion incident is established here.
  • Further reading: Controllers and persistence, Prisma lifecycle.

Sourcebackend/src/lib/prisma.ts

Sourcebackend/src/server.ts

Error handling has no uniform application boundary

  • Current behavior: Controllers usually catch database failures as operation-specific HTTP 500 responses. Mentor listing instead catches failures as HTTP 200 with { mentors: [] }. Escaped errors reach Express defaults because no custom global error handler is registered.
  • Impact: Empty mentor results can hide a failed query; clients cannot assume a consistent JSON error format or a missing-record-to-404 mapping.
  • Further reading: Responses and errors, List mentors.

Sourcebackend/src/controllers/mentorController.ts

Sourcebackend/src/app.ts

Backend checks do not implement the stated testing expectations

  • Current behavior: CONTRIBUTING.md asks for tests and coverage, but the backend has no checked-in test suite, test/coverage tooling, or test script. Backend CI installs dependencies and runs npm test --if-present; it does not run a backend build or migrations.
  • Impact: CI success supplies no endpoint, coverage, migration, or backend compilation evidence. Contributors need to state the checks actually performed and coordinate test setup when required.
  • Further reading: Contribution workflow, Endpoint verification.

Sourcebackend/package.json

Source.github/workflows/ci.yml

Configuration & deployment

Environment examples do not express runtime precedence

  • Current behavior: OAuth frontend destination precedence is NEXT_PUBLIC_FRONTEND_BASE_URL → FRONTEND_BASE_URL → FRONTEND_URL. backend/env.example omits the first alias and includes frontend-only NEXT_PUBLIC_API_URL. Backend and frontend are separate processes.
  • Impact: An earlier alias can override an expected value, and setting the frontend API URL only in backend/.env does not configure the frontend.
  • Further reading: OAuth destinations.

Sourcebackend/env.example

Sourcebackend/src/controllers/authController.ts

Build output does not match the start script

  • Current behavior: Backend build runs prisma generate && tsc; start runs node dist/server.js. TypeScript's rootDir and outDir are commented out, so compilation does not establish that dist/ artifact. CONTRIBUTING.md also lists a nonexistent root dev:backend script.
  • Impact: Script names do not establish a working build/start path. Use the verified development package context, and distinguish compilation from startup verification.
  • Further reading: Build and start, Project commands.

Sourcebackend/package.json

Sourcebackend/tsconfig.json

Public Vercel routing remains unverified

  • Current behavior: Serverless wrappers retain/add /api, while Express mounts unprefixed routes. Checked-in Vercel configuration contains headers but no reconciling rewrite; its static allowed-origin value is a comma-separated list. Hosted settings and production request traces are absent.
  • Impact: This is deployment uncertainty, not a confirmed production outage. Local routes do not prove public URLs or effective CORS headers; verify the hosted dispatch before documenting a production contract.
  • Further reading: Production routing.

Sourcebackend/api/[...all].ts

Sourcebackend/vercel.json

API consistency

Validation and persistence requirements differ

  • Current behavior: Shared Zod middleware discards parsed values; validation coverage varies by domain. Event/mentor creation schemas allow omitted imageUrl, while controllers require it and Mentor.imageUrl is a required database field. DELETE /users/:userId/club uses a schema requiring params.id, so ordinary requests fail validation before the removal controller.
  • Impact: A schema alone does not define the effective input contract. Normalization does not carry through, and the club-removal route is blocked by its parameter mismatch.
  • Further reading: Validation, Create a mentor, Remove club membership.

Sourcebackend/src/middleware/validate.ts

Sourcebackend/src/validators/mentors.ts

Sourcebackend/src/routes/users.ts

Sourcebackend/src/validators/blogs.ts

Field names and response envelopes vary

  • Current behavior: Event requests name their date field data, while responses use date. Registration and /auth/me return user id; password/Google login return userId. Event lists return { events, pagination }, while testimonial lists return { items, page, limit, total }.
  • Impact: Consumers need endpoint-specific mappings; a universal identity or pagination envelope would misread existing responses.
  • Further reading: Authentication API conventions, Events API, Testimonials API.

Sourcebackend/src/controllers/authController.ts

Sourcebackend/src/controllers/testimonialController.ts

Maintaining this index

When behavior changes, recheck its route, middleware, controller, schema, migrations, and configuration. Update the detailed page and this entry together, removing resolved limitations. Do not promote deployment uncertainty into a defect without runtime evidence or turn an absent feature into a promised fix.

Last updated · Edit this page on GitHub

On this page