@shohaghinfo/aerojs 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/AGENTS.md +17 -16
  2. package/README.md +117 -44
  3. package/dist/audit/audit-trail.d.ts +5 -6
  4. package/dist/audit/audit-trail.d.ts.map +1 -1
  5. package/dist/audit/audit-trail.js +5 -6
  6. package/dist/audit/audit-trail.js.map +1 -1
  7. package/dist/auth/auth-manager.d.ts +5 -5
  8. package/dist/auth/auth-manager.js +5 -5
  9. package/dist/auth/bouncer.d.ts +8 -15
  10. package/dist/auth/bouncer.d.ts.map +1 -1
  11. package/dist/auth/bouncer.js +10 -17
  12. package/dist/auth/bouncer.js.map +1 -1
  13. package/dist/auth/guards/api-token-guard.d.ts +2 -4
  14. package/dist/auth/guards/api-token-guard.d.ts.map +1 -1
  15. package/dist/auth/guards/api-token-guard.js +2 -4
  16. package/dist/auth/guards/api-token-guard.js.map +1 -1
  17. package/dist/auth/guards/jwt-guard.d.ts +3 -4
  18. package/dist/auth/guards/jwt-guard.d.ts.map +1 -1
  19. package/dist/auth/guards/jwt-guard.js +2 -3
  20. package/dist/auth/guards/jwt-guard.js.map +1 -1
  21. package/dist/auth/guards/session-guard.d.ts +2 -4
  22. package/dist/auth/guards/session-guard.d.ts.map +1 -1
  23. package/dist/auth/guards/session-guard.js +2 -4
  24. package/dist/auth/guards/session-guard.js.map +1 -1
  25. package/dist/auth/policy.js +1 -1
  26. package/dist/auth/policy.js.map +1 -1
  27. package/dist/cli/commands/make.js +5 -5
  28. package/dist/cli/runner.js +1 -1
  29. package/dist/core/application.d.ts +4 -0
  30. package/dist/core/application.d.ts.map +1 -1
  31. package/dist/core/application.js +29 -3
  32. package/dist/core/application.js.map +1 -1
  33. package/dist/core/context.d.ts +25 -0
  34. package/dist/core/context.d.ts.map +1 -1
  35. package/dist/core/context.js +43 -0
  36. package/dist/core/context.js.map +1 -1
  37. package/dist/database/drizzle.d.ts +4 -1
  38. package/dist/database/drizzle.d.ts.map +1 -1
  39. package/dist/database/drizzle.js +1 -1
  40. package/dist/database/drizzle.js.map +1 -1
  41. package/dist/database/index.d.ts +1 -0
  42. package/dist/database/index.d.ts.map +1 -1
  43. package/dist/database/index.js +1 -0
  44. package/dist/database/index.js.map +1 -1
  45. package/dist/database/knex.d.ts.map +1 -1
  46. package/dist/database/knex.js +1 -0
  47. package/dist/database/knex.js.map +1 -1
  48. package/dist/database/model-hooks.d.ts +5 -5
  49. package/dist/database/model-hooks.js +11 -11
  50. package/dist/database/model.d.ts +43 -59
  51. package/dist/database/model.d.ts.map +1 -1
  52. package/dist/database/model.js +62 -68
  53. package/dist/database/model.js.map +1 -1
  54. package/dist/database/prisma.d.ts +1 -1
  55. package/dist/database/prisma.d.ts.map +1 -1
  56. package/dist/database/prisma.js +3 -2
  57. package/dist/database/prisma.js.map +1 -1
  58. package/dist/database/query-builder.d.ts +11 -7
  59. package/dist/database/query-builder.d.ts.map +1 -1
  60. package/dist/database/query-builder.js +50 -21
  61. package/dist/database/query-builder.js.map +1 -1
  62. package/dist/database/sqlite.d.ts +26 -0
  63. package/dist/database/sqlite.d.ts.map +1 -0
  64. package/dist/database/sqlite.js +96 -0
  65. package/dist/database/sqlite.js.map +1 -0
  66. package/dist/events/event-bus.d.ts +47 -75
  67. package/dist/events/event-bus.d.ts.map +1 -1
  68. package/dist/events/event-bus.js +14 -23
  69. package/dist/events/event-bus.js.map +1 -1
  70. package/dist/index.d.ts +2 -2
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +5 -5
  73. package/dist/index.js.map +1 -1
  74. package/dist/notifications/notification-manager.d.ts +1 -1
  75. package/dist/notifications/notification-manager.js +1 -1
  76. package/dist/scheduler/scheduler.d.ts +5 -5
  77. package/dist/scheduler/scheduler.js +5 -5
  78. package/dist/session/session-driver.d.ts +2 -2
  79. package/dist/session/session-driver.js +2 -2
  80. package/dist/session/session-manager.d.ts +4 -4
  81. package/dist/session/session-manager.js +3 -3
  82. package/dist/tcp/mllp.d.ts +1 -1
  83. package/dist/tcp/mllp.js +2 -2
  84. package/dist/tcp/mllp.js.map +1 -1
  85. package/dist/validation/schema.d.ts +6 -0
  86. package/dist/validation/schema.d.ts.map +1 -1
  87. package/dist/validation/schema.js +57 -3
  88. package/dist/validation/schema.js.map +1 -1
  89. package/package.json +1 -1
package/AGENTS.md CHANGED
@@ -337,16 +337,17 @@ const db = knex({
337
337
  useKnex(db);
338
338
  ```
339
339
 
340
- #### 3. Using SQLite (`client: 'better-sqlite3'`)
341
- Change `.env` to `DB_CONNECTION=sqlite`, `DB_DATABASE=storage/database.sqlite`:
340
+ #### 3. Using SQLite (Native `useSqlite` or `better-sqlite3`)
342
341
  ```typescript
343
- import knex from 'knex';
344
- import { useKnex } from 'aerojs';
345
- import { databaseConfig } from './config/database.js';
342
+ import { useSqlite, useKnex } from 'aerojs';
343
+
344
+ // Option A: Built-in Native SQLite (Node.js >= 22 zero-dependency node:sqlite)
345
+ useSqlite('storage/database.sqlite'); // or ':memory:'
346
346
 
347
+ // Option B: SQLite via Knex (better-sqlite3)
347
348
  const db = knex({
348
349
  client: 'better-sqlite3',
349
- connection: databaseConfig.connections.sqlite,
350
+ connection: { filename: 'storage/database.sqlite' },
350
351
  useNullAsDefault: true,
351
352
  });
352
353
  useKnex(db);
@@ -813,9 +814,9 @@ router.get('/secure/download', validateSignedUrl(), async (ctx) => {
813
814
  ```bash
814
815
  aero make:job ProcessPayment
815
816
  aero make:mail OrderReceipt
816
- aero make:policy PatientPolicy
817
- aero make:event PatientAdmitted
818
- aero make:listener NotifyDoctor
817
+ aero make:policy PostPolicy
818
+ aero make:event UserRegistered
819
+ aero make:listener SendWelcomeNotification
819
820
  ```
820
821
 
821
822
  ---
@@ -823,7 +824,7 @@ aero make:listener NotifyDoctor
823
824
  ## 12. Advanced Enterprise Architecture (v0.4.0)
824
825
 
825
826
  ### 12.1 Field-Level AES-256-GCM Encryption (`Crypt`, `@encrypted`)
826
- Protect sensitive compliance data (SSN, medical records, credit cards, credentials) transparently at rest:
827
+ Protect sensitive compliance data (SSN, tax records, credentials, confidential notes) transparently at rest:
827
828
 
828
829
  ```typescript
829
830
  import { Model, encrypted, Crypt } from 'aerojs';
@@ -833,13 +834,13 @@ const ciphertext = Crypt.encrypt('secret-data');
833
834
  const plaintext = Crypt.decrypt(ciphertext);
834
835
 
835
836
  // Model field-level transparent encryption
836
- export class Patient extends Model {
837
- public static override table = 'patients';
837
+ export class AccountRecord extends Model {
838
+ public static override table = 'accounts';
838
839
  public static override primaryKey = 'id';
839
- public static override fillable = ['name', 'ssn', 'medical_record', 'diagnosis'];
840
+ public static override fillable = ['name', 'ssn', 'private_notes'];
840
841
 
841
842
  // Mark fields for automatic AES-256-GCM encryption
842
- public static override encrypted = ['ssn', 'medical_record'];
843
+ public static override encrypted = ['ssn', 'private_notes'];
843
844
 
844
845
  // Or use TypeScript property decorator:
845
846
  // @encrypted()
@@ -847,10 +848,10 @@ export class Patient extends Model {
847
848
  }
848
849
 
849
850
  // Automatically encrypted on .save() and decrypted on .find() / .all() / .toJSON()
850
- const patient = await Patient.create({
851
+ const account = await AccountRecord.create({
851
852
  name: 'John Doe',
852
853
  ssn: '123-45-6789',
853
- medical_record: 'Asthma diagnosis',
854
+ private_notes: 'Confidential client notes',
854
855
  });
855
856
  ```
856
857
 
package/README.md CHANGED
@@ -940,71 +940,144 @@ app.listen(3000);
940
940
 
941
941
  ---
942
942
 
943
- ### 22. Active Record ORM & QueryBuilder (`Model`, `DB`, `Migrator`)
943
+ ### 22. Active Record ORM, QueryBuilder & Dialects (`Model`, `DB`, `Schema`, `useSqlite`)
944
944
 
945
- Eloquent and Lucid inspired Active Record ORM with Proxy auto-wiring, relationships, and schema migrations:
945
+ AeroJS ships with a batteries-included, zero-lock-in database tier supporting **MySQL**, **PostgreSQL**, and **SQLite** (Node.js 24 zero-dependency `node:sqlite`).
946
946
 
947
+ ```text
948
+ ┌────────────────────────────────────────────────────────┐
949
+ │ AeroJS Database Tier │
950
+ ├──────────────────────────┬─────────────────────────────┤
951
+ │ Tier 1: Batteries-Included│ Tier 2: Zero Lock-In │
952
+ │ Native ORM & QueryBuilder│ External ORM Bridges │
953
+ │ ├─ Active Record Model │ ├─ Drizzle ORM │
954
+ │ ├─ Fluent QueryBuilder │ ├─ Prisma Client │
955
+ │ ├─ Schema Migrations │ └─ Knex.js │
956
+ │ └─ Native SQLite / PG / MySQL │
957
+ └──────────────────────────┴─────────────────────────────┘
958
+ ```
959
+
960
+ #### 22.1 Defining Active Record Models & Relationships
947
961
  ```typescript
948
- import { Model, DB, Schema, Migrator } from 'aero';
962
+ import { Model } from 'aerojs';
949
963
 
950
- // 1. Define Model with Relationships
951
- class User extends Model {
964
+ export class User extends Model {
952
965
  public static override table = 'users';
966
+ public static override primaryKey = 'id';
967
+ public static override fillable = ['name', 'email', 'role'];
953
968
  public static override hidden = ['password'];
954
969
  public static override softDeletes = true;
955
970
 
956
971
  public posts() {
957
972
  return this.hasMany(Post, 'user_id', 'id');
958
973
  }
974
+
975
+ public profile() {
976
+ return this.hasOne(Profile, 'user_id', 'id');
977
+ }
959
978
  }
960
979
 
961
- class Post extends Model {
980
+ export class Post extends Model {
962
981
  public static override table = 'posts';
982
+
983
+ public user() {
984
+ return this.belongsTo(User, 'user_id', 'id');
985
+ }
963
986
  }
987
+ ```
988
+
989
+ #### 22.2 Active Record Persistence & Dirty Tracking
990
+ ```typescript
991
+ // Create
992
+ const user = await User.create({ name: 'Alice', email: 'alice@aerojs.dev' });
964
993
 
965
- // 2. Active Record Operations & Mutation via Proxy
966
- const user = await User.create({ name: 'Alice', email: 'alice@aero.org' });
994
+ // Mutate via Proxied getters/setters & Dirty Tracking
967
995
  user.name = 'Alice Smith';
968
- await user.save();
996
+ await user.save(); // Only updates modified 'name' column
969
997
 
970
- // 3. Eager Loading (Solves N+1 Query Problem)
971
- const usersWithPosts = await User.query().with('posts').get();
998
+ // Eager Loading (Eliminates N+1 queries)
999
+ const usersWithPosts = await User.with('posts', 'profile').get();
972
1000
 
973
- // 4. Fluent QueryBuilder
974
- const admins = await DB.table('users')
975
- .where('role', 'admin')
976
- .orderBy('id', 'DESC')
977
- .paginate(1, 15);
1001
+ // Soft Deletes
1002
+ await user.delete(); // Sets deleted_at = NOW()
1003
+ await user.restore(); // Clears deleted_at
1004
+ ```
1005
+
1006
+ #### 22.3 Fluent QueryBuilder (`DB.table(...)`)
1007
+ ```typescript
1008
+ import { DB } from 'aerojs';
1009
+
1010
+ // Conditionals, Joins & Pagination
1011
+ const results = await DB.table('orders')
1012
+ .select('orders.*', 'users.name as customer_name')
1013
+ .join('users', 'orders.user_id', 'users.id')
1014
+ .where('orders.status', '=', 'completed')
1015
+ .whereIn('orders.currency', ['USD', 'EUR'])
1016
+ .orderBy('orders.created_at', 'DESC')
1017
+ .paginate(1, 15); // Returns { data, total, page, perPage, lastPage }
1018
+
1019
+ // Pessimistic Locking
1020
+ const order = await DB.table('orders')
1021
+ .where('id', 1)
1022
+ .forUpdate()
1023
+ .first();
1024
+
1025
+ // Atomic Transactions & Savepoints
1026
+ await DB.transaction(async (trx) => {
1027
+ await trx.table('accounts').where('id', 1).decrement('balance', 100);
1028
+ await trx.table('accounts').where('id', 2).increment('balance', 100);
1029
+ });
1030
+ ```
1031
+
1032
+ #### 22.4 Native Zero-Dependency SQLite Adapter
1033
+ ```typescript
1034
+ import { Aero, useSqlite } from 'aerojs';
1035
+
1036
+ const app = new Aero();
1037
+
1038
+ // Out-of-the-box in-memory or persistent SQLite without native compilation:
1039
+ app.useSqlite('storage/database.sqlite');
1040
+
1041
+ app.get('/items', async (ctx) => {
1042
+ const items = await ctx.sqlite.query('SELECT * FROM items WHERE is_active = ?', [1]);
1043
+ ctx.status(200).json(items);
1044
+ });
978
1045
  ```
979
1046
 
980
1047
  ---
981
1048
 
982
- ### 23. Knex, Prisma & Drizzle ORM Integrations
1049
+ ### 23. Zero Lock-In External Integrations (Drizzle, Prisma & Knex)
983
1050
 
984
- First-class adapters allowing developers to choose any database query engine while enjoying full Aero integration:
1051
+ AeroJS gives you complete freedom. You can leverage AeroJS's ultra-fast HTTP routing, middleware pipeline, authentication, websockets, job queues, and error dashboard while bringing your favorite database library:
985
1052
 
986
1053
  ```typescript
987
- import Aero from 'aero';
1054
+ import { Aero } from 'aerojs';
988
1055
  import knex from 'knex';
989
1056
  import { PrismaClient } from '@prisma/client';
990
1057
  import { drizzle } from 'drizzle-orm/node-postgres';
991
1058
 
992
1059
  const app = new Aero();
993
1060
 
994
- // 1. Knex Integration
1061
+ // 1. Pluggable Knex.js
995
1062
  app.useKnex(knex({ client: 'pg', connection: process.env.DATABASE_URL }));
996
1063
 
997
- // 2. Prisma Integration
1064
+ // 2. Pluggable Prisma Client
998
1065
  app.usePrisma(new PrismaClient());
999
1066
 
1000
- // 3. Drizzle Integration
1067
+ // 3. Pluggable Drizzle ORM
1001
1068
  app.useDrizzle(drizzle(process.env.DATABASE_URL));
1002
1069
 
1003
- app.get('/users', async (ctx) => {
1004
- // Access via context
1005
- const usersKnex = await ctx.knex('users').where('active', true);
1006
- const usersPrisma = await ctx.prisma.user.findMany();
1007
- const usersDrizzle = await ctx.drizzle.select().from(...);
1070
+ app.get('/dashboard', async (ctx) => {
1071
+ // Direct injection into request context with full TypeScript inference:
1072
+ const activeOrders = await ctx.knex('orders').where({ status: 'pending' });
1073
+ const usersPrisma = await ctx.prisma.user.findMany({ where: { active: true } });
1074
+ const drizzlePosts = await ctx.drizzle.select().from(postsTable);
1075
+
1076
+ // Or strongly-typed generics:
1077
+ const customPrisma = ctx.getPrisma<PrismaClient>();
1078
+ const customDrizzle = ctx.getDrizzle<typeof drizzleDb>();
1079
+
1080
+ ctx.status(200).json({ activeOrders, usersPrisma, drizzlePosts });
1008
1081
  });
1009
1082
  ```
1010
1083
 
@@ -1225,10 +1298,10 @@ Mail.configure({
1225
1298
 
1226
1299
  // 2. Dispatch with attachments & HTML
1227
1300
  await Mail.send((msg) => {
1228
- msg.to('patient@example.com')
1229
- .from('billing@hospital.org', 'Hospital Billing')
1301
+ msg.to('customer@example.com')
1302
+ .from('billing@example.org', 'Billing Department')
1230
1303
  .subject('Monthly Statement & Invoice')
1231
- .html('<h1>Hello!</h1><p>Please find your medical invoice attached.</p>')
1304
+ .html('<h1>Hello!</h1><p>Please find your monthly invoice attached.</p>')
1232
1305
  .attach('invoice.pdf', pdfBuffer, 'application/pdf');
1233
1306
  });
1234
1307
  ```
@@ -1306,25 +1379,25 @@ AeroJS ships with a powerful, zero-dependency fluent HTTP client built on native
1306
1379
  import { Http } from '@shohaghinfo/aerojs';
1307
1380
 
1308
1381
  // 1. Fluent API calls
1309
- const response = await Http.baseUrl('https://api.hospital-network.com/v1')
1382
+ const response = await Http.baseUrl('https://api.example.com/v1')
1310
1383
  .withToken(process.env.API_KEY!)
1311
1384
  .withQuery({ status: 'active', limit: 50 })
1312
1385
  .timeout(5000)
1313
1386
  .retry(3, 200)
1314
- .get('/patients');
1387
+ .get('/users');
1315
1388
 
1316
1389
  if (response.successful) {
1317
- const patients = response.json();
1318
- console.log('Patients fetched:', patients);
1390
+ const users = response.json();
1391
+ console.log('Users fetched:', users);
1319
1392
  }
1320
1393
 
1321
1394
  // 2. Testing Fakes (Mocking external services)
1322
1395
  Http.fake({
1323
- '/patients': [{ id: 1, name: 'Alice Smith' }],
1396
+ '/users': [{ id: 1, name: 'Alice Smith' }],
1324
1397
  '/billing': Http.response({ invoiceId: 'INV-101' }, 201),
1325
1398
  });
1326
1399
 
1327
- const res = await Http.post('https://api.hospital-network.com/v1/billing', { amount: 500 });
1400
+ const res = await Http.post('https://api.example.com/v1/billing', { amount: 500 });
1328
1401
  expect(res.status).toBe(201);
1329
1402
 
1330
1403
  Http.assertSent((req) => req.url.includes('/billing') && req.method === 'POST');
@@ -1446,24 +1519,24 @@ Ensure HIPAA, GDPR, and PCI-DSS compliance by transparently encrypting sensitive
1446
1519
  ```typescript
1447
1520
  import { Model, encrypted, Crypt } from '@shohaghinfo/aerojs';
1448
1521
 
1449
- class PatientRecord extends Model {
1450
- public static override table = 'patients';
1451
- public static override fillable = ['name', 'ssn', 'medical_history'];
1452
- public static override encrypted = ['ssn', 'medical_history'];
1522
+ class AccountRecord extends Model {
1523
+ public static override table = 'accounts';
1524
+ public static override fillable = ['name', 'ssn', 'private_notes'];
1525
+ public static override encrypted = ['ssn', 'private_notes'];
1453
1526
 
1454
1527
  @encrypted()
1455
1528
  public ssn!: string;
1456
1529
  }
1457
1530
 
1458
1531
  // 1. Create - Data is stored as aero:enc:<iv>:<tag>:<ciphertext> in the database
1459
- const patient = await PatientRecord.create({
1532
+ const account = await AccountRecord.create({
1460
1533
  name: 'Rahim Khan',
1461
1534
  ssn: '019-99-8888',
1462
- medical_history: 'Diabetes Type 2, Hypertension',
1535
+ private_notes: 'Confidential client information',
1463
1536
  });
1464
1537
 
1465
1538
  // 2. Read - Transparently decrypted on fetch
1466
- const loaded = await PatientRecord.find(patient.id);
1539
+ const loaded = await AccountRecord.find(account.id);
1467
1540
  console.log(loaded.ssn); // '019-99-8888' (Plaintext in app code)
1468
1541
 
1469
1542
  // 3. Arbitrary payload encryption via Crypt facade:
@@ -1509,7 +1582,7 @@ const app = new Aero();
1509
1582
 
1510
1583
  // Mount the dashboard with optional role-based protection
1511
1584
  app.useQueueDashboard('/__aero/queue', {
1512
- title: 'My Hospital Queue Horizon',
1585
+ title: 'AeroJS Queue Horizon',
1513
1586
  pollInterval: 3, // auto-refresh every 3s
1514
1587
  auth: (ctx) => ctx.session?.get('user')?.role === 'superadmin',
1515
1588
  });
@@ -2,12 +2,11 @@
2
2
  * @file audit-trail.ts
3
3
  * @description Immutable Audit Trail System for AeroJS.
4
4
  *
5
- * Hospital Architecture Section 38:
6
- * "হাসপাতালের কোনো মেডিকেল ও ফিন্যান্সিয়াল ডাটা ডাটাবেস থেকে কখনো DELETE করা যাবে না।
7
- * ভুল এন্ট্রি হলে তা STATUS = VOID বা CANCELLED হবে এবং রিভার্সাল এন্ট্রি পড়বে।"
5
+ * Provides tamper-evident compliance tracking for sensitive database entities.
6
+ * Ensures auditable state history without destructive data loss.
8
7
  *
9
8
  * Stores: User ID, Table/Module, Record ID, Action, Old Value, New Value,
10
- * IP Address, Timestamp, Cancellation Reason.
9
+ * IP Address, Timestamp, Reason.
11
10
  */
12
11
  export type AuditAction = 'CREATE' | 'UPDATE' | 'VOID' | 'APPROVE' | 'REJECT' | 'PRINT' | 'LOGIN' | 'LOGOUT' | 'LOCK' | 'RESTORE' | 'EXPORT';
13
12
  export interface AuditLogEntry {
@@ -80,12 +79,12 @@ export declare class AuditTrailManager {
80
79
  log(entry: AuditLogEntry): Promise<void>;
81
80
  /**
82
81
  * Get full history of changes for a specific record.
83
- * Hospital use: "Who changed this invoice? Show all modifications."
82
+ * Example: "Who modified this transaction? Show all changes."
84
83
  */
85
84
  getHistory(tableName: string, recordId: string | number): Promise<AuditLogRecord[]>;
86
85
  /**
87
86
  * Get all activity by a specific user in a time range.
88
- * Hospital use: "What did cashier #42 do during the night shift?"
87
+ * Example: "Show all actions performed by user #42 today."
89
88
  */
90
89
  getUserActivity(userId: string | number, from?: Date, to?: Date): Promise<AuditLogRecord[]>;
91
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"audit-trail.d.ts","sourceRoot":"","sources":["../../src/audit/audit-trail.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit-trail.d.ts","sourceRoot":"","sources":["../../src/audit/audit-trail.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,11 @@
2
2
  * @file audit-trail.ts
3
3
  * @description Immutable Audit Trail System for AeroJS.
4
4
  *
5
- * Hospital Architecture Section 38:
6
- * "হাসপাতালের কোনো মেডিকেল ও ফিন্যান্সিয়াল ডাটা ডাটাবেস থেকে কখনো DELETE করা যাবে না।
7
- * ভুল এন্ট্রি হলে তা STATUS = VOID বা CANCELLED হবে এবং রিভার্সাল এন্ট্রি পড়বে।"
5
+ * Provides tamper-evident compliance tracking for sensitive database entities.
6
+ * Ensures auditable state history without destructive data loss.
8
7
  *
9
8
  * Stores: User ID, Table/Module, Record ID, Action, Old Value, New Value,
10
- * IP Address, Timestamp, Cancellation Reason.
9
+ * IP Address, Timestamp, Reason.
11
10
  */
12
11
  import { DB } from '../database/connection.js';
13
12
  /**
@@ -107,14 +106,14 @@ export class AuditTrailManager {
107
106
  }
108
107
  /**
109
108
  * Get full history of changes for a specific record.
110
- * Hospital use: "Who changed this invoice? Show all modifications."
109
+ * Example: "Who modified this transaction? Show all changes."
111
110
  */
112
111
  async getHistory(tableName, recordId) {
113
112
  return await this.driver.getHistory(tableName, recordId);
114
113
  }
115
114
  /**
116
115
  * Get all activity by a specific user in a time range.
117
- * Hospital use: "What did cashier #42 do during the night shift?"
116
+ * Example: "Show all actions performed by user #42 today."
118
117
  */
119
118
  async getUserActivity(userId, from, to) {
120
119
  return await this.driver.getUserActivity(userId, from, to);
@@ -1 +1 @@
1
- {"version":3,"file":"audit-trail.js","sourceRoot":"","sources":["../../src/audit/audit-trail.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit-trail.js","sourceRoot":"","sources":["../../src/audit/audit-trail.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * @file auth-manager.ts
3
3
  * @description Central Auth Manager for AeroJS.
4
4
  * Manages multiple named guards (session, jwt, api) and exposes ctx.auth.use('guard').
5
- * Hospital use: ctx.auth.use('session') for cashiers, ctx.auth.use('jwt') for doctors.
5
+ * Example: ctx.auth.use('session') for web dashboard, ctx.auth.use('jwt') for mobile API.
6
6
  */
7
7
  import type { AeroContext } from '../core/context.js';
8
8
  import type { AuthUser } from './guards/guard.js';
@@ -47,10 +47,10 @@ export declare class Auth {
47
47
  * Guards are lazily instantiated per request.
48
48
  *
49
49
  * @example
50
- * // Cashier session auth
50
+ * // Web session auth
51
51
  * await ctx.auth.use('session').authenticate();
52
52
  *
53
- * // Doctor JWT auth
53
+ * // Mobile / API JWT auth
54
54
  * const user = await ctx.auth.use('jwt').authenticate();
55
55
  */
56
56
  use(name?: string): any;
@@ -88,8 +88,8 @@ export declare function authPlugin(manager: AuthManager, sessionManager?: Sessio
88
88
  * Throws UnauthorizedError if not authenticated.
89
89
  *
90
90
  * @example
91
- * router.get('/cashier/dashboard', handler).middleware(auth('session'));
92
- * router.get('/api/doctor/patients', handler).middleware(auth('jwt'));
91
+ * router.get('/dashboard', handler).middleware(auth('session'));
92
+ * router.get('/api/users', handler).middleware(auth('jwt'));
93
93
  */
94
94
  export declare function auth(guardName?: string): Middleware;
95
95
  //# sourceMappingURL=auth-manager.d.ts.map
@@ -2,7 +2,7 @@
2
2
  * @file auth-manager.ts
3
3
  * @description Central Auth Manager for AeroJS.
4
4
  * Manages multiple named guards (session, jwt, api) and exposes ctx.auth.use('guard').
5
- * Hospital use: ctx.auth.use('session') for cashiers, ctx.auth.use('jwt') for doctors.
5
+ * Example: ctx.auth.use('session') for web dashboard, ctx.auth.use('jwt') for mobile API.
6
6
  */
7
7
  import { SessionGuard } from './guards/session-guard.js';
8
8
  import { JwtGuard } from './guards/jwt-guard.js';
@@ -28,10 +28,10 @@ export class Auth {
28
28
  * Guards are lazily instantiated per request.
29
29
  *
30
30
  * @example
31
- * // Cashier session auth
31
+ * // Web session auth
32
32
  * await ctx.auth.use('session').authenticate();
33
33
  *
34
- * // Doctor JWT auth
34
+ * // Mobile / API JWT auth
35
35
  * const user = await ctx.auth.use('jwt').authenticate();
36
36
  */
37
37
  use(name) {
@@ -115,8 +115,8 @@ export function authPlugin(manager, sessionManager) {
115
115
  * Throws UnauthorizedError if not authenticated.
116
116
  *
117
117
  * @example
118
- * router.get('/cashier/dashboard', handler).middleware(auth('session'));
119
- * router.get('/api/doctor/patients', handler).middleware(auth('jwt'));
118
+ * router.get('/dashboard', handler).middleware(auth('session'));
119
+ * router.get('/api/users', handler).middleware(auth('jwt'));
120
120
  */
121
121
  export function auth(guardName) {
122
122
  return async (ctx, next) => {
@@ -8,10 +8,10 @@
8
8
  * - Policy-based authorization: ctx.bouncer.authorize(DiscountPolicy, 'approve', discount)
9
9
  * - Data-scoped checks: enforcing branch-level data isolation
10
10
  *
11
- * Hospital use:
12
- * - Section 22: Discount approval matrix (cashier 0%, supervisor 5%, MS 15%, CEO any)
13
- * - Section 37: Maker-Checker dual control for refunds, POs, supplier payments
14
- * - Section 25: Branch-scoped data access (operator sees only own branch)
11
+ * Enterprise use:
12
+ * - Role-based authorization matrix
13
+ * - Maker-Checker dual control for approvals and transactions
14
+ * - Branch-scoped or organization-scoped data access
15
15
  */
16
16
  import type { AuthUser } from '../auth/guards/guard.js';
17
17
  import type { Middleware } from '../core/types.js';
@@ -22,7 +22,7 @@ export type PolicyConstructor = new () => PolicyContract;
22
22
  export interface PermissionStore {
23
23
  /**
24
24
  * Returns all roles for a given user ID.
25
- * Example: ['cashier', 'ipd_operator']
25
+ * Example: ['member', 'editor', 'admin']
26
26
  */
27
27
  getRoles(userId: string | number): Promise<string[]>;
28
28
  /**
@@ -72,13 +72,7 @@ export declare class Bouncer {
72
72
  */
73
73
  cannot(permission: string): Promise<boolean>;
74
74
  /**
75
- * Hospital-specific: Check discount approval authority.
76
- *
77
- * Rules (Section 22):
78
- * cashier → 0%
79
- * supervisor → up to 5%
80
- * ms → up to 15%
81
- * director/ceo → unlimited
75
+ * Enterprise approval check: Check approval authority threshold based on role.
82
76
  *
83
77
  * @example
84
78
  * if (!await ctx.bouncer.canApproveDiscount(12.5)) {
@@ -87,11 +81,10 @@ export declare class Bouncer {
87
81
  */
88
82
  canApproveDiscount(percent: number): Promise<boolean>;
89
83
  /**
90
- * Hospital-specific: Check if user belongs to a specific branch.
91
- * Enforces Section 25 — branch data scoping.
84
+ * Enterprise data scoping: Check if user belongs to a specific organizational branch or tenant.
92
85
  *
93
86
  * @example
94
- * await ctx.bouncer.assertBranch(patient.branchId);
87
+ * await ctx.bouncer.assertBranch(resource.branchId);
95
88
  */
96
89
  assertBranch(resourceBranchId: string | number): Promise<void>;
97
90
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"bouncer.d.ts","sourceRoot":"","sources":["../../src/auth/bouncer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,MAAM,WAAW,cAAc;IAC7B,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAClF;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,cAAc,CAAC;AAIzD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAErD;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC5D;AAID,qBAAa,OAAO;IAClB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,KAAK,CAAC,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAAqC;gBAEzC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,eAAe;IAK1D;;OAEG;YACW,SAAS;IAUvB;;OAEG;YACW,eAAe;IAU7B;;;;;OAKG;IACU,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM/C;;;;;OAKG;IACU,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAMrD;;;;;OAKG;IACU,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMtD;;OAEG;IACU,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzD;;;;;;;;;;;;;OAaG;IACU,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUlE;;;;;;OAMG;IACU,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3E;;;;;;;OAOG;IACU,SAAS,CACpB,WAAW,EAAE,iBAAiB,EAC9B,MAAM,EAAE,MAAM,EACd,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,OAAO,CAAC,IAAI,CAAC;IAqBhB;;OAEG;IACU,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlD;;OAEG;IACU,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAK1D;AAID,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAC,CAAkB;IAEzB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAKvC,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO;CAG/C;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC;AAEnD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU,CAOjE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAS1D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAOhE"}
1
+ {"version":3,"file":"bouncer.d.ts","sourceRoot":"","sources":["../../src/auth/bouncer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,MAAM,WAAW,cAAc;IAC7B,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAClF;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,cAAc,CAAC;AAIzD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAErD;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC5D;AAID,qBAAa,OAAO;IAClB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,KAAK,CAAC,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAAqC;gBAEzC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,eAAe;IAK1D;;OAEG;YACW,SAAS;IAUvB;;OAEG;YACW,eAAe;IAU7B;;;;;OAKG;IACU,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM/C;;;;;OAKG;IACU,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAMrD;;;;;OAKG;IACU,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMtD;;OAEG;IACU,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzD;;;;;;;OAOG;IACU,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUlE;;;;;OAKG;IACU,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3E;;;;;;;OAOG;IACU,SAAS,CACpB,WAAW,EAAE,iBAAiB,EAC9B,MAAM,EAAE,MAAM,EACd,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,OAAO,CAAC,IAAI,CAAC;IAqBhB;;OAEG;IACU,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlD;;OAEG;IACU,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAK1D;AAID,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAC,CAAkB;IAEzB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAKvC,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO;CAG/C;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC;AAEnD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU,CAOjE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAS1D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAOhE"}
@@ -8,10 +8,10 @@
8
8
  * - Policy-based authorization: ctx.bouncer.authorize(DiscountPolicy, 'approve', discount)
9
9
  * - Data-scoped checks: enforcing branch-level data isolation
10
10
  *
11
- * Hospital use:
12
- * - Section 22: Discount approval matrix (cashier 0%, supervisor 5%, MS 15%, CEO any)
13
- * - Section 37: Maker-Checker dual control for refunds, POs, supplier payments
14
- * - Section 25: Branch-scoped data access (operator sees only own branch)
11
+ * Enterprise use:
12
+ * - Role-based authorization matrix
13
+ * - Maker-Checker dual control for approvals and transactions
14
+ * - Branch-scoped or organization-scoped data access
15
15
  */
16
16
  import { ForbiddenError, UnauthorizedError } from '../core/errors.js';
17
17
  // ─── Bouncer Core ─────────────────────────────────────────────────────────────
@@ -96,13 +96,7 @@ export class Bouncer {
96
96
  return !(await this.can(permission));
97
97
  }
98
98
  /**
99
- * Hospital-specific: Check discount approval authority.
100
- *
101
- * Rules (Section 22):
102
- * cashier → 0%
103
- * supervisor → up to 5%
104
- * ms → up to 15%
105
- * director/ceo → unlimited
99
+ * Enterprise approval check: Check approval authority threshold based on role.
106
100
  *
107
101
  * @example
108
102
  * if (!await ctx.bouncer.canApproveDiscount(12.5)) {
@@ -115,18 +109,17 @@ export class Bouncer {
115
109
  const roles = await this.loadRoles();
116
110
  if (roles.includes('ceo') || roles.includes('director') || roles.includes('admin'))
117
111
  return true;
118
- if (roles.includes('ms') || roles.includes('medical_superintendent'))
112
+ if (roles.includes('manager') || roles.includes('lead'))
119
113
  return percent <= 15;
120
- if (roles.includes('supervisor') || roles.includes('incharge'))
114
+ if (roles.includes('supervisor'))
121
115
  return percent <= 5;
122
- return percent <= 0; // cashier — no discount authority
116
+ return percent <= 0;
123
117
  }
124
118
  /**
125
- * Hospital-specific: Check if user belongs to a specific branch.
126
- * Enforces Section 25 — branch data scoping.
119
+ * Enterprise data scoping: Check if user belongs to a specific organizational branch or tenant.
127
120
  *
128
121
  * @example
129
- * await ctx.bouncer.assertBranch(patient.branchId);
122
+ * await ctx.bouncer.assertBranch(resource.branchId);
130
123
  */
131
124
  async assertBranch(resourceBranchId) {
132
125
  if (!this.user)