Build Backlog
All confirmed and planned work items across every feature. Items are added here as each feature is documented. Check the box to confirm a task is ready to build.
π΄ Critical β Security (fix before anything else)
Section titled βπ΄ Critical β Security (fix before anything else)β-
Fix JWT secrets in wrangler.toml Remove
JWT_SECRETandREFRESH_SECRET_KEYfrombackend/wrangler.tomland move to Cloudflare secrets viawrangler secret put. Generate new values β the current ones are burned. File:backend/wrangler.toml -
Add server-side VFS permission enforcement
PUT /api/documents/:id/statusaccepts any status from any authenticated agent. Mirror thecheckCanManageTickets()pattern fromtickets.jsinto acheckCanUpdateVfsStatus()function that validates the callerβs agent type permission against the target status. File:backend/routes/documents.js -
Add rate limiting to auth endpoints
express-rate-limitis installed but never applied. Add to/api/auth/loginand/api/auth/register. File:backend/index.js
π‘ Role Architecture β Foundation changes
Section titled βπ‘ Role Architecture β Foundation changesβ-
Add
userTiercolumn tousersDistinguish Shanvi internal staff (INTERNAL) from external partners (EXTERNAL). Currently both use role=AGENT, making it impossible to cleanly separate staff from partners without string-matching agentType names. File: DB migration +backend/routes/admin.js -
Migrate
agentTypetoagentTypeIdFKusers.agentTypestores a name string. Renaming an agent type silently breaks all users assigned to it. AddagentTypeId INTcolumn referencingagent_types.idand migrate existing data. File: DB migration + all routes that readagentType -
Add
trustLevelcolumn tousersValues:STANDARD | HIGH. Controls FD upload behaviour β STANDARD uploads go to Pending Review, HIGH uploads publish immediately. Default:STANDARD. File: DB migration +backend/routes/tickets.js -
Add
UPLOAD_FD_INVENTORYpermission to permission set New permission that can be granted to agents. Unlocks the FD inventory upload section in their dashboard. Not a separate role β an additional permission on the Agent role. Files:backend/routes/admin.js, frontend permission checks -
Add
uploadedByFK tofd_ticketsTrack which user uploaded which FD ticket. Required for the marketplace model where external sellers manage their own inventory. File: DB migration +backend/routes/tickets.js -
FD upload approval queue Admin view listing all
fd_ticketswith statusPENDING_REVIEW. Admin can approve (make live) or reject. Only affects uploads fromtrustLevel = STANDARDsellers. Files:backend/routes/tickets.js, frontend admin dashboard -
Duplicate detection on FD upload Before inserting a new FD ticket, check for existing active ticket with same route + date + airline. Return a 409 conflict if duplicate found. File:
backend/routes/tickets.js -
Add SUPER_ADMIN role Currently only one admin level. SUPER_ADMIN can manage other admins, access full audit logs, and configure system-wide settings. Regular ADMIN cannot demote or delete a SUPER_ADMIN. Files:
backend/middleware/auth.js,backend/routes/admin.js
π‘ VFS Tracking β New builds
Section titled βπ‘ VFS Tracking β New buildsβ-
Dispatch batch model Create
dispatch_batchesandbatch_documentstables. One batch = one courier trip with multiple documents. Schema is defined in the VFS tracking docs. Files: DB migration +backend/routes/documents.js -
Batch creation endpoint + bulk status update
POST /api/documents/batchesβ Shanvi staff creates a batch, assigns document IDs, triggers bulk status update toDISPATCHED_TO_SHANVIorVFS_AFTER_SHANVI. File:backend/routes/documents.js -
Batch UI for Shanvi staff Screen to select multiple pending documents, enter courier name + handoff date, and create a batch. Should show batch history. File:
frontend/src/components/Dashboard/VFS/ -
Add
vfsOutcomecolumn todocumentsTrackAPPROVED/REJECTEDas a separate column so the pipeline status can continue flowing after VFS returns the passport. CurrentlyREJECTEDis used as a pipeline status which blocks the flow. File: DB migration +backend/routes/documents.js -
Fix duplicate stage labels in UI Stages 2 and 6 both display βDocument on Wayβ. Stages 3 and 5 both display βDocument at Shanviβ. Make labels unique β e.g., βAt Shanvi (Pre-VFS)β / βAt Shanvi (Post-VFS)β. File:
frontend/src/components/Dashboard/VFS/VfsTrackingFlow.tsx
π‘ High β Existing bugs
Section titled βπ‘ High β Existing bugsβ-
Fix file URLs broken in production (R2)
getFileUrl()returns/uploads/filenamewhich only works in local dev. In the Cloudflare Worker environment this path doesnβt exist. Set R2 bucket to public, configure custom domain, updategetFileUrl. File:backend/utils/storage.js -
Fix unauthenticated
/submit-paymentendpoint ReplacedPOST /:id/submit-payment(guessable integer ID) withPOST /pay/:paymentToken. Token (48-char hex) is generated at submission creation and returned in the response. Token is nulled out after use so it canβt be reused. Rate limited to 5 attempts per IP per 15 minutes. DB migration addspaymentTokencolumn on startup. Files:backend/routes/submissions.js,backend/index.js -
Fix agent type stored by name instead of ID
users.agentTypestores the name string. If an admin renames an agent type, all assigned users silently break. AddagentTypeId INTcolumn and migrate. File: DB migration +backend/routes/admin.js
π’ Low β Tech debt
Section titled βπ’ Low β Tech debtβ-
Extract transit detail normalization in tickets.js ~50 lines of airport lookup + JSON normalization are copy-pasted between
POST /andPUT /:id. Extract tonormalizeTransitDetails(). File:backend/routes/tickets.js -
Move db promise wrappers to shared utility
all(),run(),get()wrappers are copy-pasted across route files. Move tobackend/utils/db-helpers.js. -
Store
displayIdat creation time Currently computed fromidon every response. If records are deleted and IDs recycled, display IDs could repeat. Store as a unique column. Files: DB migration + affected routes -
Break up Dashboard.tsx Holds state and fetches data for every tab on mount regardless of active tab. Refactor to lazy-loaded tab panels or per-feature data fetching hooks. File:
frontend/src/pages/Dashboard.tsx -
Adopt a database migration tool Schema changes currently happen via runtime
ALTER TABLEguards scattered in route files. Adopt Drizzle ORM + Drizzle Kit for versioned, rollback-capable migrations. -
Set up staging environment No staging environment β all changes go straight to production. Set up a staging Worker + D1 + Cloudflare Pages preview branch.