Appearance
entitlement-service
Service untuk manage feature access, subscriptions, dan entitlements.
Source Code References
Untuk Claude: Gunakan path ini untuk akses langsung ke source code.
| Item | Path |
|---|---|
| Repository | /Users/joko/Documents/projects/entitlement-service |
| Analytics Module | src/analytics/ |
| Analytics Controller | src/analytics/analytics.controller.ts |
| Analytics Service | src/analytics/analytics.service.ts |
| Naluri Service | src/naluri/naluri.service.ts |
| Internal Schema | prisma/schema.prisma |
| Naluri Core Schema | prisma/naluri-core.prisma |
| Database Service | src/common/database/database.service.ts |
| Naluri DB Service | src/common/database/naluri-db.service.ts |
Tech Stack
| Technology | Version | Purpose |
|---|---|---|
| NestJS | 11.x | Framework |
| Prisma | 6.x | ORM |
| PostgreSQL | - | Database (dual connection) |
| TypeScript | 5.x | Language |
| Yarn | 4.x | Package Manager |
Project Structure
src/
├── common/
│ ├── database/
│ │ ├── database.module.ts
│ │ ├── database.service.ts # Internal DB
│ │ └── naluri-db.service.ts # Naluri Core DB (read-only)
│ └── utils/
├── analytics/ # Focus Dashboard & analytics
│ ├── analytics.controller.ts
│ ├── analytics.service.ts
│ └── dto/
├── feature-access/ # Feature access checks
│ ├── feature-access.controller.ts
│ └── feature-access.service.ts
├── features/ # Feature definitions
├── naluri/ # Naluri Core queries
│ ├── naluri.module.ts
│ └── naluri.service.ts
├── organisation/ # Organization management
├── plans/ # Plan management
├── subscriptions/ # Subscription management
└── app.module.ts
prisma/
├── schema.prisma # Internal database schema
└── naluri-core.prisma # Naluri Core read-only schemaDual Database Architecture
┌─────────────────────────────────────────────────────────────┐
│ entitlement-service │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ DatabaseService │ │ NaluriDatabaseService│ │
│ │ @prisma/client │ │ @prisma/naluri-core │ │
│ │ │ │ -client │ │
│ └─────────┬──────────┘ └─────────┬──────────┘ │
│ │ │ │
│ │ DATABASE_URL │ CORE_DATABASE_URL │
│ ▼ ▼ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ Internal DB │ │ Naluri Core DB │ │
│ │ (Read/Write) │ │ (Read-Only) │ │
│ │ │ │ │ │
│ │ - subscriptions │ │ - users │ │
│ │ - features │ │ - coupons * │ │
│ │ - permissions │ │ - coupon_codes * │ │
│ │ - plans │ │ │ │
│ │ - analytics_* │ │ * Proposed │ │
│ └────────────────────┘ └────────────────────┘ │
└─────────────────────────────────────────────────────────────┘Database Schemas
Internal Database (schema.prisma)
prisma
// Key models
model Plans { ... }
model Features { ... }
model Subscriptions { ... }
model Permissions { ... }
// Analytics models
model AnalyticUsers { ... }
model AnalyticSponsorCodes { ... }
model AnalyticUserSponsorAccess { ... }Naluri Core Database (naluri-core.prisma)
prisma
// Currently only Users
model Users {
id String @id
email String
couponId String? @map("coupon_id")
@@map("users")
}
// Proposed additions for Focus Dashboard
model Coupons { ... }
model CouponCodes { ... }Key Services
NaluriService
File: src/naluri/naluri.service.ts
Wrapper untuk query Naluri Core database.
typescript
@Injectable()
export class NaluriService {
constructor(private readonly db: NaluriDatabaseService) {}
async getUserIdByEmail(email: string) {
return await this.db.users.findFirst({
where: { email },
select: { id: true },
});
}
async getCouponIdByUserEmail(email: string) {
return await this.db.users.findFirst({
where: { email },
select: { couponId: true },
});
}
}FeatureAccessService
File: src/feature-access/feature-access.service.ts
Check user feature access based on subscriptions.
typescript
async getUserFeatureAccess(email: string) {
// 1. Get user's couponId from Naluri Core
const user = await this.naluriService.getCouponIdByUserEmail(email);
if (!user) return 101; // User not found
if (!user.couponId) return 102; // No coupon
// 2. Get subscriptions by couponId
const subscriptions = await this.subscriptionService.getByCouponId(user.couponId);
// 3. Get features for those plans
const planIds = subscriptions.map((s) => s.plan.id);
const features = await this.featureService.getFeaturesByPlanIds(planIds);
return features;
}AnalyticsService
File: src/analytics/analytics.service.ts
Manage analytics users and sponsor code access.
Current endpoints:
/analytics/users- CRUD for AnalyticUsers/analytics/sponsor-codes- CRUD for AnalyticSponsorCodes/analytics/user-sponsor-access- CRUD for access mapping/analytics/access-by-email- Get sponsor codes by user email
Missing endpoints (to be implemented):
/analytics/search-users- Search users/analytics/manage-access- Enable/disable access/analytics/focus-dashboard/{id}- Get dashboard details
API Endpoints
Feature Access
| Endpoint | Method | Description |
|---|---|---|
/feature-access | GET | Get user feature access by email |
Subscriptions
| Endpoint | Method | Description |
|---|---|---|
/subscriptions | GET | List subscriptions |
/subscriptions | POST | Create subscription |
/subscriptions/{id} | GET/PATCH/DELETE | CRUD |
Analytics
| Endpoint | Method | Description |
|---|---|---|
/analytics/users | GET/POST | List/create analytic users |
/analytics/users/{id} | GET/PATCH/DELETE | CRUD |
/analytics/sponsor-codes | GET/POST | List/create sponsor codes |
/analytics/sponsor-codes/{id} | GET/PATCH/DELETE | CRUD |
/analytics/user-sponsor-access | GET/POST | List/create access |
/analytics/access-by-email | GET | Get by email |
Environment Variables
| Variable | Description |
|---|---|
DATABASE_URL | Internal entitlement database |
CORE_DATABASE_URL | Naluri Core database (read-only) |
PORT | Server port (default: 3001) |
Setup Commands
bash
# Install dependencies
yarn install
# Generate Prisma clients
yarn prisma generate # Internal DB
yarn prisma generate --schema=prisma/naluri-core.prisma # Naluri Core
# Run migrations
yarn prisma migrate dev
# Start development
yarn start:devLast updated: March 2026