Module dependency graph
GreekManage exposes 9 license-toggleable modules to org admins. Each module is implemented by one or more Django apps in the backend. This page maps that relationship and shows what depends on what.
Modules ↔ apps
Always-on apps (not module-gated)
Some apps are core platform infrastructure and can't be turned off:
These provide:
| App | Provides |
|---|---|
accounts | User model, profile, password, data export, account deletion |
authentication | SAML, OAuth, LinkedIn, encrypted credential storage |
common | Permissions, middleware, audit log, base model classes |
organizations | Org, region, chapter, membership, admin tiers |
members | Member profiles, degrees, work history, skills, recognitions |
notifications | In-app + email, preferences, digests |
platform | Platform admin, module licensing, email config |
feedback | User feedback inbox |
Inter-app dependencies
Some apps depend on others — disabling a module that another app needs causes graceful degradation, not crashes.
Notable deps
- AI Services indexes content from
documents,forums,members,compliance. Without those modules enabled, the chatbot's retrieval scope shrinks but it still works for what's indexed. - Learning can link to
compliancerequirements (e.g., "passing this course satisfies hazing-prevention compliance"). If Compliance is off, learning still works but the auto-mark-complete on compliance won't fire. - Notifications is always on but each module emits its own event types. Disabling a module mutes its event types.
- Common wires audit logging into write-heavy apps via middleware — every module benefits.
Effects of disabling a module
This is enforced consistently:
- Frontend:
<ModuleGuard module="community">wraps gated routes - Backend:
@module_required("community")decorator on viewsets (or middleware-level check) - Celery: tasks check
OrganizationModule.is_enabled(...)before doing work
Module enablement table
| Module | Apps | Default? | Pricing tier (typical) |
|---|---|---|---|
operations | compliance, elections, finances, retention, plus the PNM/recruitment slice of organizations | Off (recommended on) | Standard |
community | forums, events, photos, activity | Off (recommended on) | Standard |
documents | documents | Off | Standard |
learning | learning | Off | Add-on |
foundation | foundation | Off | Add-on |
alumni | alumni | Off | Standard |
messaging | messaging | Off | Standard |
ai_services | ai_services | Off | Add-on (per-query metered) |
data_export | backups | Off | Add-on (large orgs) |
Defaults are "off" on org creation — platform admins enable based on the customer's contract.
operations is the one module that does not map cleanly onto whole apps. PNM/recruitment lives in apps/organizations, a core app that is otherwise ungated, so as of v0.73.15 the license is enforced on the PNM URL prefixes specifically — via MODULE_URL_PATTERNS for the authenticated endpoints, in the view layer for the five public unauthenticated ones (those set authentication_classes = [], so no org context exists for the middleware to check), and per-org inside the PNM daily-digest task and the PNM conversion KPI. Enumerating URL prefixes rather than an app is deliberate; a blanket gate on /api/organizations/ would lock unlicensed orgs out of core membership management.
Where to look in code
| Need | File |
|---|---|
| Module list | apps/organizations/models.py — OrganizationModule.MODULE_CHOICES |
| Per-org licensing | apps/organizations/models.py — OrganizationModule(org=, module=, is_enabled=) |
| Module guard (frontend) | frontend/src/components/auth/module-guard.tsx |
| Module decorator (backend) | apps/common/decorators.py — @module_required |