Frontend Implementation Specification
Related documentation: Kisum System · Backend implementation · Backend Auth · Backend Core · Backend Admin · Frontend Applications · Frontend Admin Specification
Current implementation snapshot
Section titled “Current implementation snapshot”- Implemented now: Kisum frontend is not one single application. The local workspace currently contains multiple frontend applications with different stacks and maturity levels.
- Implemented now:
Frontend-Kisumis the main product app and is a large Next.js App Router codebase with React 19. - Implemented now:
Frontend-Kisum-Adminis the platform-admin app and uses React Router 7 with React 19. - Implemented now:
Frontend-Kisum-Financeis a separate finance-focused Next.js application with internal finance routes and a live vendor portal. - Implemented now:
Frontend-Kisum-Venuesis a real Next.js 16 + React 19 App Router application with live venue CRUD/operations/reporting surfaces. - Implemented now:
Frontend-Kisum-Artistsis no longer a chassis-only repo; the FE-Phase 0–7 app surface is shipped. - Implemented now:
Frontend-Kisum-Promotersis a real dedicated promoter persona app with/booking/*, venue marketplace, billing, and legacy promoter CRM surfaces. - Implemented now:
Frontend-Kisum-Websiteis the public marketing SPA and hands checkout/payment toSystem-Kisum-Checkout. - Implemented now:
Frontend-Nextktis a frontend-only Next.js ticket sales prototype with landing and event-detail purchase UI. It does not define backend ownership or checkout contracts yet. - Target architecture: frontend should converge on the shared Auth/Core/Base/module contract described in this docs site, even though the current applications are still partly fragmented by domain and history.
Status
Section titled “Status”This document is FINAL and ENFORCEABLE for frontend implementation.
It defines how the frontend must integrate with:
- Auth Backend
- Platform Core (indirectly only, never direct for access)
- Base Backend
- Module Backends
This document complements:
- Architecture documentation
- Architecture diagrams
- Architecture Permissions
- Architecture Permissions Packages
- Architecture Blueprint
- Backend Auth
- Backend Core
- Backend Core API
- Promoters Module Backend
- Access Control Integration
- Access Matrix
1. Purpose
Section titled “1. Purpose”This document explains how the frontend should work in the Kisum architecture, while also reflecting the current multi-app implementation in the local workspace.
It covers:
- login flow
- token usage
- access bootstrap
- company switching
- module visibility
- route guarding
- permission-aware UI
- request headers
- cache and refresh behavior
- what frontend is allowed to decide
- what frontend must never decide
- how the current frontend applications are split today
2. Frontend role in the architecture
Section titled “2. Frontend role in the architecture”Frontend is the UX layer.
Frontend is responsible for:
- login screens
- app shell
- company selector
- module navigation
- page rendering
- route visibility
- button visibility
- form visibility
- user interaction
Frontend is not responsible for:
- validating JWTs as security authority
- computing effective access
- deciding entitlements
- deciding company membership
- deciding permissions as source of truth
- replacing backend authorization
2.1 Current frontend applications in the workspace
Section titled “2.1 Current frontend applications in the workspace”The current workspace includes at least these active frontend codebases:
Frontend-Kisum- main user-facing product app
- Next.js App Router
- large shared/domain UI surface
Frontend-Kisum-Admin- platform staff control-plane UI
- React Router 7
- talks primarily to
Backend-Kisum-Admin
Frontend-Kisum-Finance- finance-focused app
- separate Next.js app with its own company/auth/session handling
Frontend-Kisum-Artists- standalone artist / agency app
- live operational workflow surface backed by
Backend-Kisum-Artists
Frontend-Kisum-Venues- standalone venue-management app
- Next.js App Router
- operations-first shell for venue CRM, bookings, contracts, deposits, operations, and reports
Frontend-Kisum-Promoters- standalone promoter persona app
- consumes
Backend-Kisum-Promotersplus Artists/Venues network BFF routes
Frontend-Kisum-Website- public Vite marketing site
- pricing, module marketing, geo lookup, and handoff to Checkout
Frontend-Nextkt- frontend-only ticket sales prototype
- public event discovery and event detail ticket selection UI
- static event data until a real ticketing backend/source-of-truth is defined
This means the frontend documentation must cover both:
- the target shared platform rules
- the current reality that multiple frontends still exist and need alignment
2.2 Current Venue frontend rule
Section titled “2.2 Current Venue frontend rule”Frontend-Kisum-Venues is the dedicated management surface for the venue module.
Current product contract:
- one company manages one venue in v1
- one venue contains many spaces
- spaces act like lightweight BU scopes
- multi-space bookings are supported
- admin/superadmin finalize confirmation-sensitive and contract-sensitive actions
- Finance write workflows remain outside the Venue frontend
This app should not be documented as a generic venue-detail reader. It is a venue-operations CRM.
3. Final system rule
Section titled “3. Final system rule”Frontend may use access data for UX,but backend remains the final authority.This means:
- frontend may hide a module
- frontend may show a module
- frontend may disable a button
- frontend may guard a route
But if frontend accidentally shows something, backend must still enforce the real rule.
4. Access model the frontend must respect
Section titled “4. Access model the frontend must respect”Frontend must understand that access is resolved in 3 layers:
Level 1 — Company entitlements
Section titled “Level 1 — Company entitlements”Owned by Platform Core, resolved through Auth.
Question:
- did the company buy this module?
Level 2 — Membership module grants
Section titled “Level 2 — Membership module grants”Owned by Auth.
Question:
- does this membership have this module?
Level 3 — Fine-grained permissions
Section titled “Level 3 — Fine-grained permissions”Owned by Auth.
Question:
- what actions inside the module are allowed?
Frontend must never try to compute these layers itself.
Frontend must consume the final result from Auth.
4.1 Company creation and package purchase model
Section titled “4.1 Company creation and package purchase model”Frontend must treat company creation and package purchase as backend-owned workflows.
Frontend may collect input and show progress, but it must not invent company ids or decide subscription truth locally.
Admin-created company
Section titled “Admin-created company”Runtime pattern:
Platform Admin UI -> Platform Admin Backend -> Core.companiesFrontend responsibilities:
- collect company form data
- submit to Platform Admin backend
- show lifecycle/status returned by backend
- after creation, optionally navigate to membership assignment UX
Self-serve company creation during checkout
Section titled “Self-serve company creation during checkout”Runtime pattern:
Checkout UI -> Checkout/Admin Backend -> Core.companies -> subscription flowFrontend responsibilities:
- collect company and package selection input
- submit to backend
- show pending-payment state if payment is not yet finalized
- wait for backend-confirmed status changes before unlocking tenant UX
Important rule
Section titled “Important rule”The frontend must assume the authoritative company row exists in Core first. Memberships and access only become usable after backend flows create or activate them in Auth.
5. Main frontend contract
Section titled “5. Main frontend contract”Frontend must use:
Section titled “Frontend must use:”GET /auth/meGET /auth/me/accessThese are the main access/bootstrap endpoints.
Current implementation reality
Section titled “Current implementation reality”Not every existing frontend app is fully standardized on this contract yet.
- the target contract is still
/auth/meplus/auth/me/access - admin-only UIs may also call
Backend-Kisum-Admin - older domain apps may still carry local session/company-context logic that should eventually converge on the shared Auth contract
/auth/me
Section titled “/auth/me”Used for:
- identity
- basic profile
- memberships list
- session info
/auth/me/access
Section titled “/auth/me/access”Used for:
- active company access
- effective modules
- permissions
- delegation info
- rendering decisions
6. Login flow
Section titled “6. Login flow”6.1 Login request
Section titled “6.1 Login request”Frontend calls:
POST /auth/loginRequest body example:
{ "email": "user@example.com", "password": "password123", "accountType": "internal"}6.2 Login success behavior
Section titled “6.2 Login success behavior”On successful login, frontend receives:
accessTokenrefreshTokenexpiresIntokenType
Frontend must then:
- store tokens securely
- load
/auth/me - determine active company
- call
/auth/me/access - bootstrap UI from returned access context
6.3 Login failure behavior
Section titled “6.3 Login failure behavior”Frontend must handle:
401 unauthorized403 pending_approval403 registration_rejected403 account_inactive429 rate_limited
Frontend should map these into clear user messages.
6.4 Multi-app login rule
Section titled “6.4 Multi-app login rule”All frontend apps should converge on the same identity authority:
- Auth is the only login authority
- frontend apps must not invent their own user truth
- module-specific or admin-specific frontends may vary in UI, but not in identity ownership
7. Token handling rules
Section titled “7. Token handling rules”7.1 Access token
Section titled “7.1 Access token”Use for:
- authenticated API requests
Header:
Authorization: Bearer <accessToken>Access token is short-lived.
7.2 Refresh token
Section titled “7.2 Refresh token”Use only for:
POST /auth/refreshPOST /auth/logout
Frontend must store refresh token securely.
7.3 Frontend must NOT do
Section titled “7.3 Frontend must NOT do”Frontend must not:
- put permissions in local hardcoded state as final truth
- assume JWT contains modules or permissions
- infer access from JWT payload alone
- use token contents as replacement for
/auth/me/access
8. Bootstrap flow after login
Section titled “8. Bootstrap flow after login”After login, frontend should do this sequence:
Step 1
Section titled “Step 1”Call:
GET /auth/meAuthorization: Bearer <accessToken>Step 2
Section titled “Step 2”Read memberships / available companies
Step 3
Section titled “Step 3”Select active company
Step 4
Section titled “Step 4”Call:
GET /auth/me/accessAuthorization: Bearer <accessToken>x-org: <companyId>Step 5
Section titled “Step 5”Store returned access context in frontend state
Step 6
Section titled “Step 6”Render app shell and module visibility
9. Active company model
Section titled “9. Active company model”Frontend must always have the concept of an active company.
This is the company currently selected by the user.
That company must be sent as:
x-org: <companyId>for all tenant-scoped requests.
9.1 Company switching
Section titled “9.1 Company switching”When user changes company:
- update active company state
- call
/auth/me/accessagain with newx-org - replace access context in memory
- rerender visible modules and allowed routes
- update outgoing request header source
9.2 Critical rule
Section titled “9.2 Critical rule”Frontend must never rely on an old company context after switch.
Access must be reloaded.
9.3 Package assignment vs user assignment
Section titled “9.3 Package assignment vs user assignment”Frontend must keep these concepts separate in product and UX flows:
Company package assignment
Section titled “Company package assignment”This belongs to Core.
Examples:
- company buys Basic
- company buys Finance add-on
- company is
pending_payment - company subscription becomes
active
The frontend should read these outcomes through backend responses and later through /auth/me/access.
User assignment inside the company
Section titled “User assignment inside the company”This belongs to Auth.
Examples:
- user becomes member of company
- user receives tenant role
- user receives module grants
- user receives permissions
Final frontend rule
Section titled “Final frontend rule”Do not treat package purchase as equal to user access.
The frontend must wait for Auth-resolved access because:
effective_access = company_entitlements ∩ membership_grants10. Recommended frontend state model
Section titled “10. Recommended frontend state model”Frontend should keep these as separate state domains:
10.1 Session state
Section titled “10.1 Session state”- accessToken
- refreshToken
- expiresAt
- session info
10.2 Identity state
Section titled “10.2 Identity state”- user id
- name
- globalRole
- authType
10.3 Organization state
Section titled “10.3 Organization state”- memberships
- activeCompanyId
- company list
10.4 Access state
Section titled “10.4 Access state”- tenantRole
- companyEnabledModules
- membershipGrantedModules (optional if returned)
- effectiveModules
- permissions
- delegation
- tokenVersion
- entitlementVersion
- generatedAt
11. Recommended access response shape
Section titled “11. Recommended access response shape”Frontend should be prepared for an access context similar to:
{ "companyId": "uuid", "tenantRole": "ADMIN", "companyEnabledModules": ["basic", "finance", "market"], "membershipGrantedModules": ["basic", "finance"], "effectiveModules": ["basic", "finance"], "permissions": [ "basic.dashboard.view", "basic.event.view", "finance.expense.view", "finance.expense.edit" ], "delegation": { "canBuyAddons": false, "canManageUsers": true, "grantableModules": ["basic"], "grantablePermissions": [ "basic.dashboard.view", "basic.event.view" ] }, "meta": { "tokenVersion": 2, "entitlementVersion": 8, "generatedAt": "2026-04-16T05:00:00Z" }}Frontend must treat this as rendering context, not security authority.
12. Module visibility rules
Section titled “12. Module visibility rules”Frontend should show module tiles / routes only if module exists in:
effectiveModulesExamples:
- show Basic app only if
basicexists - show Finance module only if
financeexists - show Artist only if
artistexists - show Venue only if
venueexists - show AI only if
aiexists - show Touring only if
touringexists
12.1 Important rule
Section titled “12.1 Important rule”Do not show module only because role sounds related.
Example:
FINANCErole does not automatically mean Finance moduleADMINdoes not automatically mean all modulesUSERmay still have Finance if explicitly granted
Module visibility must come from effective access, not role name.
13. Route guard rules
Section titled “13. Route guard rules”Frontend may guard routes for UX purposes.
Example:
/finance/*requiresfinance/artist/*requiresartist/venue/*requiresvenue
If missing:
- redirect
- hide route
- show “access denied” UX
But backend remains the final authority.
14. Permission-aware UI rules
Section titled “14. Permission-aware UI rules”Frontend may use permissions to control UI details.
Examples:
- show “Create Expense” button only if
finance.expense.create - show “Edit Event” button only if
basic.event.edit - show “Approve Contract” only if
market.contract.approve
This is valid and recommended.
14.1 But frontend must remember
Section titled “14.1 But frontend must remember”Permission-based UI visibility is convenience only.
Backend must still enforce.
15. Delegation-aware UI rules
Section titled “15. Delegation-aware UI rules”Frontend should use delegation info to determine whether to show:
- user management screens
- module grant controls
- permission grant controls
- add-on purchase controls
Examples:
- if
canManageUsers = false, hide user-management actions - if
canBuyAddons = false, hide upgrade/purchase actions - if
grantableModulesempty, hide module assignment UI
16. Request header rules
Section titled “16. Request header rules”16.1 Authenticated tenant request
Section titled “16.1 Authenticated tenant request”For tenant-scoped backend requests, frontend must send:
Authorization: Bearer <accessToken>x-org: <companyId>16.2 Public routes
Section titled “16.2 Public routes”Do not send auth unless needed.
16.3 Vendor routes
Section titled “16.3 Vendor routes”If vendor flow exists, use vendor auth model only on vendor routes.
Do not mix tenant x-org assumptions into vendor flows unless explicitly designed.
17. Refresh behavior
Section titled “17. Refresh behavior”Frontend must refresh access in these cases:
- after login
- after token refresh
- after company switch
- after page reload / app restore
- after module grant change
- after permission grant/revoke
- after add-on/subscription change
- after receiving backend response that indicates access changed
- after invitation acceptance flow if it changes membership
18. What frontend may cache
Section titled “18. What frontend may cache”Frontend may cache:
- last
/auth/me - last
/auth/me/access - active company id
- visible modules
- permission context
Possible locations:
- in-memory state
- app store
- short-lived session storage (if product chooses)
18.1 What frontend must NOT do with cache
Section titled “18.1 What frontend must NOT do with cache”Frontend must not:
- trust cached access forever
- assume cache beats backend
- continue showing old company access after company switch
- assume stale cached permissions are correct
When in doubt, refetch.
19. Error handling model
Section titled “19. Error handling model”Frontend must distinguish:
Authentication problem
- invalid token
- expired token
- refresh needed
- session revoked
Typical frontend behavior:
- refresh token if possible
- otherwise redirect to login
Authorization problem
- user authenticated
- request forbidden
- missing module / permission / scope
Typical frontend behavior:
- show access denied
- refresh access context if this may be stale
- rerender UI
Client/request issue
- missing or invalid
x-org - malformed request
Typical frontend behavior:
- fix request context
- recover active company state
Upstream/system issue
- Auth unavailable
- Core unavailable through Auth
- access resolution unavailable
Typical frontend behavior:
- show temporary error state
- allow retry
- do not guess access
20. Frontend route classification
Section titled “20. Frontend route classification”Frontend should classify routes as:
Tenant routes
Section titled “Tenant routes”- require JWT
- require active company
- require
/auth/me/access
Public routes
Section titled “Public routes”- no auth required
Vendor routes
Section titled “Vendor routes”- vendor auth only
Mixed routes
Section titled “Mixed routes”- must be explicitly documented
21. Recommended implementation pattern
Section titled “21. Recommended implementation pattern”21.1 Global access provider
Section titled “21.1 Global access provider”Frontend should implement a central access provider/store.
Responsibilities:
- keep current access context
- expose helpers like
hasModule()andhasPermission() - expose active company
- refresh access on demand
- clear access on logout
21.2 Suggested helper API
Section titled “21.2 Suggested helper API”Frontend should centralize helpers similar to:
hasModule("finance")hasPermission("finance.expense.view")canManageUsers()canBuyAddons()isTenantRole("ADMIN")These helpers must read from current access context, not hardcoded role assumptions.
22. Suggested page-loading pattern
Section titled “22. Suggested page-loading pattern”Example for Finance page:
- ensure session valid
- ensure active company selected
- ensure access context loaded
- check
hasModule("finance") - if no → deny route
- if yes → render page
- inside page, show/hide actions by permission
23. Suggested UI states
Section titled “23. Suggested UI states”Frontend should have explicit UI states for:
- loading session
- loading memberships
- loading access
- company selection required
- access denied
- temporary service unavailable
- session expired
This avoids confusing transitions.
24. Logout behavior
Section titled “24. Logout behavior”On logout:
- call
POST /auth/logout - clear accessToken
- clear refreshToken
- clear identity state
- clear access state
- clear active company
- redirect to login
If “logout all” is used:
- same frontend clearing behavior
25. Security rules for frontend
Section titled “25. Security rules for frontend”Frontend must never:
- store internal API keys
- call Platform Core directly for access decisions
- call internal machine routes
- trust JWT payload as full access truth
- bypass backend checks
- assume UI visibility is security
26. Relationship with Platform Core
Section titled “26. Relationship with Platform Core”Frontend should not call Platform Core directly for access.
Correct pattern:
Frontend → Auth → Corenot:
Frontend → CoreFrontend may only interact with Core indirectly through Auth or admin backend flows.
27. Relationship with Base / Module Backends
Section titled “27. Relationship with Base / Module Backends”Correct pattern:
Frontend → Base/Module BackendBackend → Auth for enforcementFrontend must not assume that because /auth/me/access says “yes”, backend will never reject.
Backend is still the final enforcement point.
28. Company and company data migration note
Section titled “28. Company and company data migration note”If some legacy systems still store companies separately, frontend should still treat:
x-org = canonical company idDo not preserve legacy mixed company-id behavior in frontend forever.
Target state:
- one canonical company id across app
29. QA / test scenarios frontend must support
Section titled “29. QA / test scenarios frontend must support”- login success
- login pending approval
- login rejected
- login inactive
- token refresh flow
- logout flow
- company switch reloads access
- access denied hides module
- backend 403 updates UI correctly
- backend 503 shows retry state
- stale cached access gets replaced after refresh
- invited user accepts invitation and sees new company after reload
30. Final rules
Section titled “30. Final rules”Frontend consumes accessFrontend does not compute accessFrontend does not enforce securityFrontend does not replace backend authorization31. Final one-line summary
Section titled “31. Final one-line summary”Frontend uses Auth access context to render the app correctly,but every real security decision is still enforced by backend services.