Skoolsewa - School Management System Docs
Developer ResourcesSystem Features

System Features Features and Flows

Complete feature list, actor journeys, business rules, and edge cases for system-features.

System Features Features and Flows

1. Documentation Evidence

Source TypeFiles or DocsWhat Was Extracted
APIsystem-features.controller.ts, API docRoute, actors, auth, response-visible behavior.
Backendsystem-features.service.ts, Backend docPermission gate, query behavior, side effects (none).

2. Feature Summary

FieldValue
Modulesystem-features
SubmoduleN/A
Primary user valueLets the panel discover, in one call, which installation-level features this school has switched on, so it can show or hide navigation and setup screens without hardcoding assumptions per deployment.
ActorsAny authenticated user (guardian, student, teacher, staff, admin, superadmin); unauthenticated callers are refused before reaching this feature.
Main entry pointsGET /api/system/features
Main outputsA response body of booleans — no persisted records, no events, no notifications.
Related docsAPI, Backend

3. Actor Matrix

ActorCan DoCannot DoAuth RequirementNotes
Guest (unauthenticated)NothingCall the endpoint at allNone availableRefused by the global JwtAuthGuard with 401 before the handler runs.
Signed-in user, no active role chosenRead enabledSee accounting setup detailJWTApplies to any audience mid-onboarding or before a role is selected.
Signed-in user, active role without an accounting permissionRead enabledSee accounting setup detailJWTIncludes most guardian, student, and teacher sessions, and staff without a fee/salary/asset sync read code.
Signed-in user, active role holding FeePayments_CREATE but none of the accounting permissionsRead enabled and paymentWriteBack (whether payments recorded in the accounting application are written back to this school)See any other setup fieldJWTOffice staff who record payments.
Signed-in user, active role holding FeeSync_READ, FeeMappings_READ, FeeIntegrations_READ, SalarySync_READ, or AssetSync_READRead enabled, configured, clientConnected, hasClients, paymentWriteBackChange any of these values through this route — it is read-onlyJWTTypically finance/admin staff and superadmin.
SuperadminSame as the permission-holding row, granted unconditionally—JWTrole.isSuperadmin short-circuits the permission lookup.

4. Capability Matrix

CapabilitySurfaceActorRoute/TriggerState ReadState WrittenLinked API Section
Learn whether accounting integration is switched onAdmin (audience-agnostic)Any signed-in userGET /api/system/featuresACCOUNTING_INTEGRATION_ENABLED env varNoneAPI §8.1
Learn whether the integration is configured and connectedAdmin (audience-agnostic)Role holding an accounting permission, or superadminSame routeKeyring state, integration_clients, integration_client_keysNoneAPI §8.1

5. User-Facing Flows

5.1 Panel loads and shapes its navigation

Summary

On login, or whenever the panel rebuilds its navigation (role switch, page refresh), it calls this endpoint to decide whether to render the accounting-integration section at all, and — for roles allowed to configure it — whether to prompt for setup or show a connected/disconnected state.

Preconditions

  • The caller has a valid session (any authenticated user).
  • No catalog, pricing, or session state is required — this is a pure configuration read.
  • No feature flag gates the route itself; ACCOUNTING_INTEGRATION_ENABLED is one of the values it reports, not a precondition for calling it.

Main Flow

StepActor/SystemActionResultSource
1PanelCalls GET /api/system/features with the session's bearer token.Request accepted by JwtAuthGuard.Controller.
2BackendRoleGuard allows the handler through unconditionally (allowlisted).No permission check at the route level.role.guard.ts:745.
3BackendReads ACCOUNTING_INTEGRATION_ENABLED; checks whether the caller's active role qualifies for setup detail.enabled always set; configured/clientConnected/hasClients set only if qualified.Service.
4PanelRenders navigation based on the returned booleans.Accounting section shown/hidden; setup screen shown only where the caller could plausibly act on it.Backend doc.

Sequence Diagram

Branches and Edge Cases

BranchConditionBehaviorError/Result
No active role yetactor.activeRole is undefinedOnly enabled returned200, minimal body
Role without accounting permissionPermission lookup misses all five codesOnly enabled returned200, minimal body
Role with accounting permission, integration disabledenabled: falseconfigured/hasClients still computed from real state; clientConnected forced false200, full body with clientConnected: false
UnauthenticatedNo valid JWTRefused before the feature runs401

6. Admin Flows

This module exposes no mutating admin action — it is a read-only disclosure endpoint. There is no create, update, delete, or restore flow to document here; configuring the integration itself (rotating keys, connecting a client) is owned by the integration module and out of scope for this page.

6.1 Admin checks accounting setup state before configuring the integration

Include route, permission, mutation side effects, cache invalidation, audit/logging, and failure branches: this flow has no mutation, no cache invalidation, and no audit entry — every step is the same single read described in §5.1, re-interpreted by the panel.

7. Lifecycle and State Transitions

This module has no entity lifecycle of its own — it reports on the lifecycle of the accounting integration, which is owned elsewhere. There is no state machine to document for system-features itself.

9. Data and Side Effects by Flow

FlowDB WritesCache EffectsJobsRealtimeAnalyticsNotifications
GET /api/system/featuresNoneNone (no-store)NoneNoneNoneNone

10. Error and Recovery Flows

ScenarioTriggerUser/System ExperienceRecoverySource
Session expiredMissing/invalid JWT401 responseRe-authenticateJwtAuthGuard (global).
Database temporarily unavailableQuery failure in clientConnected()/hasClients()500 via the global exception filterRetry the requestGlobal AllExceptionsFilter.

11. Diagrams Required Per Module

Covered above: the sequence diagram in §5.1, the flowchart in §6.1. No state machine exists (§7), so no state diagram is produced — this module has no lifecycle. No dedicated error-branch diagram beyond the table in §10, since the only failure paths are the global auth guard and an unhandled DB error, both already fully described.

12. Mandatory Feature and Flow Deep-Dive Pack

12.1 Feature Inventory With Minor Behaviors

FeatureMinor BehaviorActorTriggerUser/System ResultBackend Side EffectSource
Report enabledAlways present, regardless of roleAny signed-in userGET /api/system/featuresPanel knows if accounting exists at allRead ACCOUNTING_INTEGRATION_ENABLEDSystemFeaturesService.get
Report setup detailOmitted (not null/false) for unqualified callersRole without an accounting permissionSame routePanel sees no configured/clientConnected/hasClients keysNo extra DB read performedSystemFeaturesService.get
Force clientConnected: false while disabledSkips the DB join entirelyAny qualified caller, with the switch offSame routePanel never shows "connected" while the feature is offNo query issuedSystemFeaturesService.get
Compute hasClients regardless of enabledRuns even while the switch is offAny qualified callerSame routePanel can still show "you have a client to revoke" after disablingOne SELECT querySystemFeaturesService.get, hasClients
Superadmin bypassSkips the permission-code lookup entirelySuperadminSame routeSame setup detail as any qualified roleOne fewer DB callSystemFeaturesService.accountingAccess
no-store response headerEvery response, unconditionallyAny callerSame routeClient/proxy never caches a stale feature stateNonesystem-features.controller.ts:30

12.2 Business Process Diagram Pack

12.3 Business Rules and Policy Traceability

RuleBusiness ReasonActor ImpactEnforced InAPI ImpactBackend ImpactTests
Every signed-in caller may read enabledEvery audience's navigation needs to know whether the feature existsNo caller is blocked from the routeNO_PERMISSION_ADMIN_HANDLERS allowlistRoute carries no @Permissions()RoleGuard short-circuits to allowroute-permissions.spec.ts:127-131
Setup detail requires an accounting permission or superadminSetup state is operationally sensitive even though it is not secretNon-finance roles see a minimal bodySystemFeaturesService.accountingAccessOptional fields present/absentConditional query executionNone (no unit test exists)
clientConnected is false whenever enabled is falseA client cannot be meaningfully "connected" to a switched-off integrationConsistent UI even during a disabled windowSystemFeaturesService.getField always coherent with enabledSkips a query when disabledNone
Response is never cachedFeature state can change between deploys/config edits and must reflect immediatelyPanel always sees current state@Header("Cache-Control", "no-store")HTTP header on every responseNoneNone

12.4 Tradeoffs and Product Rationale

Product DecisionUser BenefitEngineering BenefitAlternativeTradeoffRisk
Unpermissioned route, service-level field gatingEvery audience gets a working navigation call without needing a bespoke permission grantOne route serves every audience instead of duplicating per-audience endpointsA dedicated SystemFeatures_READ permissionSlightly less explicit in the permission catalogLow — the gate is centralized in one function
@CurrentUser instead of @CurrentAdminA caller mid-onboarding, with no active role, still gets a usable answerNo special-casing needed elsewhere for "no active role yet" callersRequire an active roleWould 401/403 sessions that legitimately have none yetNone material — the degraded response (enabled only) is deliberately safe

12.5 Flow Edge-Case Matrix

FlowEdge CaseTriggerExpected BehaviorUser/System FeedbackSource
Feature readNo active roleSession mid-onboardingMinimal bodyenabled onlySystemFeaturesService.accountingAccess
Feature readIntegration disabled, caller qualifiedACCOUNTING_INTEGRATION_ENABLED=falseFull body, clientConnected forced falsePanel shows disabled + still-revokable clients if anySystemFeaturesService.get
Feature readUnauthenticatedNo/invalid JWTRequest refused before reaching the feature401Global JwtAuthGuard
Feature readConcurrent callsTwo simultaneous requestsBoth resolve independently; no shared stateTwo consistent, possibly differing (if config changed) responsesStateless service

12.6 Flow-to-Data Trace

FlowReadsWritesCacheJobs/EventsResponse Fields
GET /api/system/featuresConfig, keyring state, integration_clients, integration_client_keysNoneNoneNoneenabled, configured, clientConnected, hasClients, paymentWriteBack

12.7 Experience Quality Checklist

  • The doc explains what the actor is trying to accomplish (shape navigation around installation features).
  • The doc explains what the backend does that the actor does not see (the permission-gated field omission).
  • The doc covers every minor flow and branch (no-role, no-permission, disabled-integration, superadmin).
  • The doc includes the one relevant flow type — no admin mutation, no worker/system flow exists in this module.
  • The doc explains business logic, tradeoffs, and rationale.
  • The doc maps the flow to the API route and backend behavior.
  • The doc includes diagrams appropriate to the flow.
  • The doc covers edge cases; no failure-recovery beyond auth/DB errors exists.

13. Completion Checklist

  • Every feature and minor behavior is listed.
  • Every actor has allowed and forbidden behavior stated.
  • The one flow includes steps, branches, and diagrams.
  • No lifecycle exists in this module; stated explicitly rather than fabricated.
  • The flow links to the API and backend docs.
  • No TDD dependency exists for this module.

See Also