model module {
id String @id @default(cuid())
code String @unique // MFG, SCM, SALES, FINANCE, HR, SYS
name String
sort_order Int?
is_active Boolean @default(true)
}
๐ฆ Subscription Plan
Subscription Plan defines only user limits.
Modules are linked separately to clients.
model subscription_plan {
id String @id @default(cuid())
code String @unique // BASIC, SILVER, GOLD, PLATINUM, BLACK
name String
max_users Int
is_active Boolean @default(true)
}
๐ข Client Table
model client {
id String @id // A0001
name String
plan_id String
is_active Boolean @default(true)
}
๐ฆ Client Module Mapping
model client_module {
id String @id @default(cuid())
client_id String
module_id String
is_active Boolean @default(true)
}
๐ค Users Table
model user {
id String @id @default(cuid())
name String
mobile String? @unique
email String? @unique
role UserRole
client_id String
is_active Boolean @default(true)
telegram_id String?
telegram_linked Boolean @default(false)
current_session_id String?
otp_code String?
otp_expires_at DateTime?
}
enum UserRole {
SYSTEM
ADMIN
MANAGER
STAFF
READ_ONLY
}
๐ Authentication & Authorization
Login Flow
User enters mobile/email
System sends OTP via:
Email
SMS (optional)
User enters OTP
System validates + generates JWT
Session created with:
userId
role
clientId
๐ Client Handling
ClientId Format
A0001, A0002, A0003...
Rules
All tables must include client_id
All queries must filter by client_id
Prevent cross-company data access
client_id should be stored in HTTP Cookie
Frontend should never manually send client_id
client_id should be automatically injected from session/cookie