@bloomneo/appkit 1.2.9
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.
- package/LICENSE +21 -0
- package/README.md +902 -0
- package/bin/appkit.js +71 -0
- package/bin/commands/generate.js +1050 -0
- package/bin/templates/backend/README.md.template +39 -0
- package/bin/templates/backend/api.http.template +0 -0
- package/bin/templates/backend/docs/APPKIT_CLI.md +507 -0
- package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +61 -0
- package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +2539 -0
- package/bin/templates/backend/package.json.template +34 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.http.template +29 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.route.ts.template +36 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.service.ts.template +88 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.types.ts.template +18 -0
- package/bin/templates/backend/src/api/lib/api-router.ts.template +84 -0
- package/bin/templates/backend/src/api/server.ts.template +188 -0
- package/bin/templates/backend/tsconfig.api.json.template +24 -0
- package/bin/templates/backend/tsconfig.json.template +40 -0
- package/bin/templates/feature/feature.http.template +63 -0
- package/bin/templates/feature/feature.route.ts.template +36 -0
- package/bin/templates/feature/feature.service.ts.template +81 -0
- package/bin/templates/feature/feature.types.ts.template +23 -0
- package/bin/templates/feature-db/feature.http.template +63 -0
- package/bin/templates/feature-db/feature.model.ts.template +74 -0
- package/bin/templates/feature-db/feature.route.ts.template +58 -0
- package/bin/templates/feature-db/feature.service.ts.template +231 -0
- package/bin/templates/feature-db/feature.types.ts.template +25 -0
- package/bin/templates/feature-db/schema-addition.prisma.template +9 -0
- package/bin/templates/feature-db/seeding/README.md.template +57 -0
- package/bin/templates/feature-db/seeding/feature.seed.js.template +67 -0
- package/bin/templates/feature-user/schema-addition.prisma.template +19 -0
- package/bin/templates/feature-user/user.http.template +157 -0
- package/bin/templates/feature-user/user.model.ts.template +244 -0
- package/bin/templates/feature-user/user.route.ts.template +379 -0
- package/bin/templates/feature-user/user.seed.js.template +182 -0
- package/bin/templates/feature-user/user.service.ts.template +426 -0
- package/bin/templates/feature-user/user.types.ts.template +127 -0
- package/dist/auth/auth.d.ts +182 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +477 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/defaults.d.ts +104 -0
- package/dist/auth/defaults.d.ts.map +1 -0
- package/dist/auth/defaults.js +374 -0
- package/dist/auth/defaults.js.map +1 -0
- package/dist/auth/index.d.ts +70 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +94 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/cache/cache.d.ts +118 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +249 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/defaults.d.ts +63 -0
- package/dist/cache/defaults.d.ts.map +1 -0
- package/dist/cache/defaults.js +193 -0
- package/dist/cache/defaults.js.map +1 -0
- package/dist/cache/index.d.ts +101 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +203 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/strategies/memory.d.ts +138 -0
- package/dist/cache/strategies/memory.d.ts.map +1 -0
- package/dist/cache/strategies/memory.js +348 -0
- package/dist/cache/strategies/memory.js.map +1 -0
- package/dist/cache/strategies/redis.d.ts +105 -0
- package/dist/cache/strategies/redis.d.ts.map +1 -0
- package/dist/cache/strategies/redis.js +318 -0
- package/dist/cache/strategies/redis.js.map +1 -0
- package/dist/config/config.d.ts +62 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +107 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/defaults.d.ts +44 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +217 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +163 -0
- package/dist/config/index.js.map +1 -0
- package/dist/database/adapters/mongoose.d.ts +106 -0
- package/dist/database/adapters/mongoose.d.ts.map +1 -0
- package/dist/database/adapters/mongoose.js +480 -0
- package/dist/database/adapters/mongoose.js.map +1 -0
- package/dist/database/adapters/prisma.d.ts +106 -0
- package/dist/database/adapters/prisma.d.ts.map +1 -0
- package/dist/database/adapters/prisma.js +494 -0
- package/dist/database/adapters/prisma.js.map +1 -0
- package/dist/database/defaults.d.ts +87 -0
- package/dist/database/defaults.d.ts.map +1 -0
- package/dist/database/defaults.js +271 -0
- package/dist/database/defaults.js.map +1 -0
- package/dist/database/index.d.ts +137 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +490 -0
- package/dist/database/index.js.map +1 -0
- package/dist/email/defaults.d.ts +100 -0
- package/dist/email/defaults.d.ts.map +1 -0
- package/dist/email/defaults.js +400 -0
- package/dist/email/defaults.js.map +1 -0
- package/dist/email/email.d.ts +139 -0
- package/dist/email/email.d.ts.map +1 -0
- package/dist/email/email.js +316 -0
- package/dist/email/email.js.map +1 -0
- package/dist/email/index.d.ts +176 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +251 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/strategies/console.d.ts +90 -0
- package/dist/email/strategies/console.d.ts.map +1 -0
- package/dist/email/strategies/console.js +268 -0
- package/dist/email/strategies/console.js.map +1 -0
- package/dist/email/strategies/resend.d.ts +84 -0
- package/dist/email/strategies/resend.d.ts.map +1 -0
- package/dist/email/strategies/resend.js +266 -0
- package/dist/email/strategies/resend.js.map +1 -0
- package/dist/email/strategies/smtp.d.ts +77 -0
- package/dist/email/strategies/smtp.d.ts.map +1 -0
- package/dist/email/strategies/smtp.js +286 -0
- package/dist/email/strategies/smtp.js.map +1 -0
- package/dist/error/defaults.d.ts +40 -0
- package/dist/error/defaults.d.ts.map +1 -0
- package/dist/error/defaults.js +75 -0
- package/dist/error/defaults.js.map +1 -0
- package/dist/error/error.d.ts +140 -0
- package/dist/error/error.d.ts.map +1 -0
- package/dist/error/error.js +200 -0
- package/dist/error/error.js.map +1 -0
- package/dist/error/index.d.ts +145 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/index.js +145 -0
- package/dist/error/index.js.map +1 -0
- package/dist/event/defaults.d.ts +111 -0
- package/dist/event/defaults.d.ts.map +1 -0
- package/dist/event/defaults.js +378 -0
- package/dist/event/defaults.js.map +1 -0
- package/dist/event/event.d.ts +171 -0
- package/dist/event/event.d.ts.map +1 -0
- package/dist/event/event.js +391 -0
- package/dist/event/event.js.map +1 -0
- package/dist/event/index.d.ts +173 -0
- package/dist/event/index.d.ts.map +1 -0
- package/dist/event/index.js +302 -0
- package/dist/event/index.js.map +1 -0
- package/dist/event/strategies/memory.d.ts +122 -0
- package/dist/event/strategies/memory.d.ts.map +1 -0
- package/dist/event/strategies/memory.js +331 -0
- package/dist/event/strategies/memory.js.map +1 -0
- package/dist/event/strategies/redis.d.ts +115 -0
- package/dist/event/strategies/redis.d.ts.map +1 -0
- package/dist/event/strategies/redis.js +434 -0
- package/dist/event/strategies/redis.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/defaults.d.ts +67 -0
- package/dist/logger/defaults.d.ts.map +1 -0
- package/dist/logger/defaults.js +213 -0
- package/dist/logger/defaults.js.map +1 -0
- package/dist/logger/index.d.ts +84 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +101 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/logger.d.ts +165 -0
- package/dist/logger/logger.d.ts.map +1 -0
- package/dist/logger/logger.js +843 -0
- package/dist/logger/logger.js.map +1 -0
- package/dist/logger/transports/console.d.ts +102 -0
- package/dist/logger/transports/console.d.ts.map +1 -0
- package/dist/logger/transports/console.js +276 -0
- package/dist/logger/transports/console.js.map +1 -0
- package/dist/logger/transports/database.d.ts +153 -0
- package/dist/logger/transports/database.d.ts.map +1 -0
- package/dist/logger/transports/database.js +539 -0
- package/dist/logger/transports/database.js.map +1 -0
- package/dist/logger/transports/file.d.ts +146 -0
- package/dist/logger/transports/file.d.ts.map +1 -0
- package/dist/logger/transports/file.js +464 -0
- package/dist/logger/transports/file.js.map +1 -0
- package/dist/logger/transports/http.d.ts +128 -0
- package/dist/logger/transports/http.d.ts.map +1 -0
- package/dist/logger/transports/http.js +401 -0
- package/dist/logger/transports/http.js.map +1 -0
- package/dist/logger/transports/webhook.d.ts +152 -0
- package/dist/logger/transports/webhook.d.ts.map +1 -0
- package/dist/logger/transports/webhook.js +485 -0
- package/dist/logger/transports/webhook.js.map +1 -0
- package/dist/queue/defaults.d.ts +66 -0
- package/dist/queue/defaults.d.ts.map +1 -0
- package/dist/queue/defaults.js +205 -0
- package/dist/queue/defaults.js.map +1 -0
- package/dist/queue/index.d.ts +124 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +116 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/queue.d.ts +156 -0
- package/dist/queue/queue.d.ts.map +1 -0
- package/dist/queue/queue.js +387 -0
- package/dist/queue/queue.js.map +1 -0
- package/dist/queue/transports/database.d.ts +165 -0
- package/dist/queue/transports/database.d.ts.map +1 -0
- package/dist/queue/transports/database.js +595 -0
- package/dist/queue/transports/database.js.map +1 -0
- package/dist/queue/transports/memory.d.ts +143 -0
- package/dist/queue/transports/memory.d.ts.map +1 -0
- package/dist/queue/transports/memory.js +415 -0
- package/dist/queue/transports/memory.js.map +1 -0
- package/dist/queue/transports/redis.d.ts +203 -0
- package/dist/queue/transports/redis.d.ts.map +1 -0
- package/dist/queue/transports/redis.js +744 -0
- package/dist/queue/transports/redis.js.map +1 -0
- package/dist/security/defaults.d.ts +64 -0
- package/dist/security/defaults.d.ts.map +1 -0
- package/dist/security/defaults.js +159 -0
- package/dist/security/defaults.js.map +1 -0
- package/dist/security/index.d.ts +110 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +160 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security.d.ts +138 -0
- package/dist/security/security.d.ts.map +1 -0
- package/dist/security/security.js +419 -0
- package/dist/security/security.js.map +1 -0
- package/dist/storage/defaults.d.ts +79 -0
- package/dist/storage/defaults.d.ts.map +1 -0
- package/dist/storage/defaults.js +358 -0
- package/dist/storage/defaults.js.map +1 -0
- package/dist/storage/index.d.ts +153 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +242 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/storage.d.ts +151 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +439 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/storage/strategies/local.d.ts +117 -0
- package/dist/storage/strategies/local.d.ts.map +1 -0
- package/dist/storage/strategies/local.js +368 -0
- package/dist/storage/strategies/local.js.map +1 -0
- package/dist/storage/strategies/r2.d.ts +130 -0
- package/dist/storage/strategies/r2.d.ts.map +1 -0
- package/dist/storage/strategies/r2.js +470 -0
- package/dist/storage/strategies/r2.js.map +1 -0
- package/dist/storage/strategies/s3.d.ts +121 -0
- package/dist/storage/strategies/s3.d.ts.map +1 -0
- package/dist/storage/strategies/s3.js +461 -0
- package/dist/storage/strategies/s3.js.map +1 -0
- package/dist/util/defaults.d.ts +77 -0
- package/dist/util/defaults.d.ts.map +1 -0
- package/dist/util/defaults.js +193 -0
- package/dist/util/defaults.js.map +1 -0
- package/dist/util/index.d.ts +97 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +165 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/util.d.ts +145 -0
- package/dist/util/util.d.ts.map +1 -0
- package/dist/util/util.js +481 -0
- package/dist/util/util.js.map +1 -0
- package/package.json +234 -0
package/README.md
ADDED
|
@@ -0,0 +1,902 @@
|
|
|
1
|
+
# Bloomneo AppKit ๐
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@bloomneo/appkit)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://github.com/bloomneo/appkit)
|
|
7
|
+
|
|
8
|
+
> Previously published as `@voilajsx/appkit`. Same code, new home, new namespace. See the [migration note](#scope-change) below.
|
|
9
|
+
|
|
10
|
+
> **Minimal and framework agnostic Node.js toolkit designed for AI agentic
|
|
11
|
+
> backend development**
|
|
12
|
+
|
|
13
|
+
**Zero configuration. Enterprise features by default. Optimized for both human
|
|
14
|
+
developers and AI code generation.**
|
|
15
|
+
|
|
16
|
+
## ๐ What Bloomneo AppKit Really Is
|
|
17
|
+
|
|
18
|
+
Bloomneo AppKit is a **complete Node.js development toolkit** that eliminates
|
|
19
|
+
the complexity of building production-ready applications. Instead of juggling
|
|
20
|
+
dozens of libraries and configuration files, you get 12 integrated modules that
|
|
21
|
+
work together seamlessly.
|
|
22
|
+
|
|
23
|
+
### **How Developers Can Leverage AppKit**
|
|
24
|
+
|
|
25
|
+
**๐ฏ For Rapid Development**
|
|
26
|
+
|
|
27
|
+
- **One function per module**: `authClass.get()`, `databaseClass.get()`,
|
|
28
|
+
`securityClass.get()`
|
|
29
|
+
- **Instant setup**: No configuration files, just environment variables
|
|
30
|
+
- **Production patterns**: Enterprise-grade security and scalability built-in
|
|
31
|
+
|
|
32
|
+
**๐๏ธ For Maintainable Architecture**
|
|
33
|
+
|
|
34
|
+
- **Consistent APIs**: Same `{moduleClass}.get()` pattern across all modules
|
|
35
|
+
- **Progressive complexity**: Start simple, scale to enterprise automatically
|
|
36
|
+
- **Type-safe**: Full TypeScript support with intelligent IntelliSense
|
|
37
|
+
|
|
38
|
+
**โก For Performance**
|
|
39
|
+
|
|
40
|
+
- **Smart defaults**: Memory caching, connection pooling, resource management
|
|
41
|
+
- **Auto-scaling**: Modules automatically upgrade (Memory โ Redis โ Database)
|
|
42
|
+
- **Optimized**: Battle-tested patterns for high-throughput applications
|
|
43
|
+
|
|
44
|
+
## ๐ค Enhanced for AI-Driven Development
|
|
45
|
+
|
|
46
|
+
While perfectly designed for human developers, AppKit excels in AI-assisted
|
|
47
|
+
development:
|
|
48
|
+
|
|
49
|
+
- **๐ฏ Predictable Code Generation**: AI agents generate consistent, working
|
|
50
|
+
applications
|
|
51
|
+
- **๐ LLM-Optimized Documentation**: Every function includes clear usage
|
|
52
|
+
patterns
|
|
53
|
+
- **๐ Built-in Best Practices**: Security, scalability, and maintainability by
|
|
54
|
+
default
|
|
55
|
+
- **โ๏ธ Non-Ambiguous APIs**: Clear function signatures prevent common mistakes
|
|
56
|
+
|
|
57
|
+
### **Why This Matters for Developers**
|
|
58
|
+
|
|
59
|
+
| Traditional Approach | Bloomneo AppKit Approach |
|
|
60
|
+
| ----------------------------------------- | --------------------------------------- |
|
|
61
|
+
| Research โ Configure โ Integrate โ Secure | **Import โ Use โ Deploy** |
|
|
62
|
+
| Multiple libraries, version conflicts | **Integrated modules, tested together** |
|
|
63
|
+
| Manual scaling decisions | **Environment-driven auto-scaling** |
|
|
64
|
+
| Security implemented later | **Security enabled by default** |
|
|
65
|
+
| Inconsistent error handling | **Unified error patterns** |
|
|
66
|
+
|
|
67
|
+
## ๐ข Enterprise Benefits
|
|
68
|
+
|
|
69
|
+
### **Progressive Complexity**
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Day 1: Simple development
|
|
73
|
+
const auth = authClass.get();
|
|
74
|
+
const token = auth.signToken({ userId: 123, role: 'user', level: 'basic' });
|
|
75
|
+
|
|
76
|
+
// Month 6: Multi-tenant (just add environment variable)
|
|
77
|
+
// VOILA_DB_TENANT=auto
|
|
78
|
+
const database = await databaseClass.get(); // Now auto-filtered by tenant
|
|
79
|
+
|
|
80
|
+
// Year 1: Multi-organization enterprise (same code)
|
|
81
|
+
// ORG_ACME=postgresql://acme.aws.com/prod
|
|
82
|
+
const acmeDatabase = await databaseClass.org('acme').get(); // Enterprise scaling
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## ๐ Quick Start
|
|
86
|
+
|
|
87
|
+
**Two Ways to Use AppKit:**
|
|
88
|
+
|
|
89
|
+
**๐ฆ As a Library** - Install AppKit modules into your existing Node.js/Express projects (NestJS, Fastify, Koa, etc.):
|
|
90
|
+
```bash
|
|
91
|
+
npm install @bloomneo/appkit
|
|
92
|
+
```
|
|
93
|
+
Import modules directly: `import { authClass, databaseClass } from '@bloomneo/appkit'`
|
|
94
|
+
|
|
95
|
+
**๐ Complete Microservice Scaffolding** - Use AppKit CLI to generate enterprise-ready backend applications:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Step 1: Install AppKit CLI globally
|
|
99
|
+
npm install -g @bloomneo/appkit
|
|
100
|
+
|
|
101
|
+
# Check if you have the latest version
|
|
102
|
+
npm list -g @bloomneo/appkit
|
|
103
|
+
|
|
104
|
+
# Step 2: Create your app
|
|
105
|
+
appkit generate app myproject
|
|
106
|
+
cd myproject && npm run dev:api
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Done.** Your API is running with authentication, database, and enterprise features ready at http://localhost:3000/api
|
|
110
|
+
|
|
111
|
+
### **Add Features Instantly**
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Add custom feature
|
|
115
|
+
appkit generate feature product
|
|
116
|
+
|
|
117
|
+
# Add complete authentication system
|
|
118
|
+
appkit generate feature user
|
|
119
|
+
|
|
120
|
+
# Add database-enabled feature
|
|
121
|
+
appkit generate feature order --db
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### **Library Integration Example**
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# For library usage in existing projects
|
|
128
|
+
npm install @bloomneo/appkit
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { authClass } from '@bloomneo/appkit/auth';
|
|
133
|
+
import { databaseClass } from '@bloomneo/appkit/database';
|
|
134
|
+
import { errorClass } from '@bloomneo/appkit/error';
|
|
135
|
+
import { loggerClass } from '@bloomneo/appkit/logger';
|
|
136
|
+
|
|
137
|
+
const auth = authClass.get();
|
|
138
|
+
const database = await databaseClass.get();
|
|
139
|
+
const error = errorClass.get();
|
|
140
|
+
const logger = loggerClass.get('api');
|
|
141
|
+
|
|
142
|
+
// Protected API endpoint
|
|
143
|
+
app.post(
|
|
144
|
+
'/api/users',
|
|
145
|
+
auth.requireRole('admin.tenant'),
|
|
146
|
+
error.asyncRoute(async (req, res) => {
|
|
147
|
+
const user = auth.user(req);
|
|
148
|
+
|
|
149
|
+
if (!req.body.email) {
|
|
150
|
+
throw error.badRequest('Email required');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const newUser = await database.user.create({ data: req.body });
|
|
154
|
+
logger.info('User created', { userId: newUser.id });
|
|
155
|
+
|
|
156
|
+
res.json({ user: newUser });
|
|
157
|
+
})
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
// Error handling middleware (must be last)
|
|
161
|
+
app.use(error.handleErrors());
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Result**: Production-ready API with authentication, database, error handling,
|
|
165
|
+
and logging. **Zero configuration needed.**
|
|
166
|
+
|
|
167
|
+
## ๐ ๏ธ AppKit CLI
|
|
168
|
+
|
|
169
|
+
### **Project Generation**
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Create complete backend application
|
|
173
|
+
appkit generate app [name]
|
|
174
|
+
|
|
175
|
+
# What you get:
|
|
176
|
+
# โ
TypeScript setup with proper configuration
|
|
177
|
+
# โ
Express server with auto-discovery routing
|
|
178
|
+
# โ
Environment variables with secure random keys
|
|
179
|
+
# โ
Database integration ready
|
|
180
|
+
# โ
Complete documentation included
|
|
181
|
+
# โ
Production-ready npm scripts
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### **Feature Generation**
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Basic feature (route + service + types)
|
|
188
|
+
appkit generate feature product
|
|
189
|
+
|
|
190
|
+
# Database-enabled feature (+ model + HTTP tests)
|
|
191
|
+
appkit generate feature order --db
|
|
192
|
+
|
|
193
|
+
# Complete authentication system (9-role hierarchy)
|
|
194
|
+
appkit generate feature user
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### **Generated Project Structure**
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
myproject/
|
|
201
|
+
โโโ docs/ # Complete documentation
|
|
202
|
+
โ โโโ APPKIT_CLI.md # CLI reference
|
|
203
|
+
โ โโโ APPKIT_LLM_GUIDE.md # AI integration guide
|
|
204
|
+
โ โโโ APPKIT_COMMENTS_GUIDELINES.md # Code standards
|
|
205
|
+
โโโ src/api/
|
|
206
|
+
โ โโโ server.ts # Main server
|
|
207
|
+
โ โโโ lib/api-router.ts # Auto-discovery routing
|
|
208
|
+
โ โโโ features/ # Feature-based architecture
|
|
209
|
+
โ โโโ welcome/ # Default endpoints
|
|
210
|
+
โ โโโ [your-features]/ # Generated features
|
|
211
|
+
โโโ .env # Secure environment variables
|
|
212
|
+
โโโ package.json # With backend scripts
|
|
213
|
+
โโโ README.md # Project-specific guide
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## ๐ญ Complete Module Ecosystem
|
|
217
|
+
|
|
218
|
+
| # | Module | Category | Purpose | Details |
|
|
219
|
+
| --- | --------------------------------------- | ----------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
220
|
+
| 1 | **[Auth](/src/auth/README.md)** | ๐ง Infrastructure | JWT tokens, dual token system, role-level permissions | `authClass.get()` - Login tokens (users) + API tokens (services), role.level hierarchy (user.basic โ admin.system), automatic inheritance |
|
|
221
|
+
| 2 | **[Database](/src/database/README.md)** | ๐ง Infrastructure | Multi-tenant, progressive scaling | `databaseClass.get()` - Auto-tenant filtering, org management (.org()), mandatory future-proofing with tenant_id |
|
|
222
|
+
| 3 | **[Security](/src/security/README.md)** | ๐ง Infrastructure | CSRF, rate limiting, encryption | `securityClass.get()` - Enterprise-grade by default, AES-256-GCM encryption, input sanitization |
|
|
223
|
+
| 4 | **[Error](/src/error/README.md)** | ๐ง Infrastructure | HTTP status codes, semantic errors | `errorClass.get()` - Framework-agnostic middleware, semantic error types (badRequest, unauthorized) |
|
|
224
|
+
| 5 | **[Cache](/src/cache/README.md)** | ๐ Data & Communication | Memory โ Redis auto-scaling | `cacheClass.get('namespace')` - Namespace isolation, TTL management, getOrSet pattern |
|
|
225
|
+
| 6 | **[Storage](/src/storage/README.md)** | ๐ Data & Communication | Local โ S3/R2 auto-scaling | `storageClass.get()` - CDN integration, signed URLs, automatic provider detection |
|
|
226
|
+
| 7 | **[Queue](/src/queue/README.md)** | ๐ Data & Communication | Memory โ Redis โ DB scaling | `queueClass.get()` - Background jobs, scheduling, retry logic with exponential backoff |
|
|
227
|
+
| 8 | **[Email](/src/email/README.md)** | ๐ Data & Communication | Console โ SMTP โ Resend | `emailClass.get()` - Templates, multi-provider, automatic strategy selection |
|
|
228
|
+
| 9 | **[Event](/src/event/README.md)** | ๐ Data & Communication | Memory โ Redis distribution | `eventClass.get('namespace')` - Real-time, pub/sub, wildcard patterns (user.\*) |
|
|
229
|
+
| 10 | **[Util](/src/util/README.md)** | ๐ ๏ธ Developer Experience | 12 essential utilities | `utilClass.get()` - Safe property access (get), performance helpers (debounce, chunk) |
|
|
230
|
+
| 11 | **[Config](/src/config/README.md)** | ๐ ๏ธ Developer Experience | Environment variables | `configClass.get()` - Type-safe, UPPER_SNAKE_CASE convention, validation included |
|
|
231
|
+
| 12 | **[Logger](/src/logger/README.md)** | ๐ ๏ธ Developer Experience | Structured logging | `loggerClass.get('component')` - Multi-transport, auto-scaling (Console โ File โ HTTP) |
|
|
232
|
+
|
|
233
|
+
### **Category Summary**
|
|
234
|
+
|
|
235
|
+
- **๐ง Infrastructure (4 modules)**: Core application foundation - auth,
|
|
236
|
+
database, security, error handling
|
|
237
|
+
- **๐ Data & Communication (5 modules)**: Data flow and external interactions -
|
|
238
|
+
cache, storage, queue, email, events
|
|
239
|
+
- **๐ ๏ธ Developer Experience (3 modules)**: Development productivity - utilities,
|
|
240
|
+
configuration, logging
|
|
241
|
+
|
|
242
|
+
## ๐ Environment-Driven Progressive Scaling
|
|
243
|
+
|
|
244
|
+
### **Development** (Zero Configuration)
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
npm start # Memory cache, local storage, console logs
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### **Production** (Auto-Detection)
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# Set these environment variables - everything scales automatically
|
|
254
|
+
DATABASE_URL=postgresql://prod-db/app # โ Database persistence
|
|
255
|
+
REDIS_URL=redis://prod-cache:6379 # โ Distributed cache/queue
|
|
256
|
+
AWS_S3_BUCKET=prod-assets # โ Cloud storage + CDN
|
|
257
|
+
RESEND_API_KEY=re_production_key # โ Professional email
|
|
258
|
+
VOILA_DB_TENANT=auto # โ Multi-tenant mode
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Same code. Different environment. Enterprise features automatically enabled.**
|
|
262
|
+
|
|
263
|
+
## ๐ข Enterprise-Ready Examples
|
|
264
|
+
|
|
265
|
+
### **Multi-Tenant SaaS API**
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
import { authClass } from '@bloomneo/appkit/auth';
|
|
269
|
+
import { databaseClass } from '@bloomneo/appkit/database';
|
|
270
|
+
import { securityClass } from '@bloomneo/appkit/security';
|
|
271
|
+
import { cacheClass } from '@bloomneo/appkit/cache';
|
|
272
|
+
|
|
273
|
+
const auth = authClass.get();
|
|
274
|
+
const database = await databaseClass.get(); // Auto-filtered by tenant
|
|
275
|
+
const security = securityClass.get();
|
|
276
|
+
const cache = cacheClass.get('api');
|
|
277
|
+
|
|
278
|
+
// User endpoint (tenant-isolated)
|
|
279
|
+
app.get(
|
|
280
|
+
'/api/users',
|
|
281
|
+
auth.requireLogin(),
|
|
282
|
+
security.requests(100, 900000), // Rate limiting
|
|
283
|
+
async (req, res) => {
|
|
284
|
+
const users = await cache.getOrSet(
|
|
285
|
+
'users',
|
|
286
|
+
async () => {
|
|
287
|
+
return await database.user.findMany(); // Only current tenant
|
|
288
|
+
},
|
|
289
|
+
300
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
res.json(users);
|
|
293
|
+
}
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
// Admin endpoint (cross-tenant access)
|
|
297
|
+
app.get(
|
|
298
|
+
'/api/admin/analytics',
|
|
299
|
+
auth.requireRole('admin.system'),
|
|
300
|
+
async (req, res) => {
|
|
301
|
+
const dbTenants = await databaseClass.getTenants(); // All tenants
|
|
302
|
+
const stats = await dbTenants.user.groupBy({
|
|
303
|
+
by: ['tenant_id'],
|
|
304
|
+
_count: true,
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
res.json(stats);
|
|
308
|
+
}
|
|
309
|
+
);
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### **Real-Time Chat Application**
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import { eventClass } from '@bloomneo/appkit/event';
|
|
316
|
+
import { authClass } from '@bloomneo/appkit/auth';
|
|
317
|
+
import { databaseClass } from '@bloomneo/appkit/database';
|
|
318
|
+
|
|
319
|
+
const events = eventClass.get();
|
|
320
|
+
const auth = authClass.get();
|
|
321
|
+
const database = await databaseClass.get();
|
|
322
|
+
|
|
323
|
+
// Handle user connections
|
|
324
|
+
events.on('user.connected', async (data) => {
|
|
325
|
+
const { userId, socketId } = data;
|
|
326
|
+
|
|
327
|
+
// Join user to their rooms
|
|
328
|
+
await events.emit('socket.join', {
|
|
329
|
+
socketId,
|
|
330
|
+
rooms: [`user:${userId}`, `tenant:${data.tenantId}`],
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// Handle chat messages
|
|
335
|
+
events.on('message.send', async (data) => {
|
|
336
|
+
const message = await database.message.create({
|
|
337
|
+
data: {
|
|
338
|
+
content: data.content,
|
|
339
|
+
userId: data.userId,
|
|
340
|
+
roomId: data.roomId,
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
// Broadcast to room (tenant-isolated)
|
|
345
|
+
await events.emit('message.broadcast', {
|
|
346
|
+
roomId: data.roomId,
|
|
347
|
+
message: {
|
|
348
|
+
id: message.id,
|
|
349
|
+
content: message.content,
|
|
350
|
+
user: { name: data.userName },
|
|
351
|
+
timestamp: message.createdAt,
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// REST API integration
|
|
357
|
+
app.post('/api/notifications', auth.requireLogin(), async (req, res) => {
|
|
358
|
+
const user = auth.user(req);
|
|
359
|
+
|
|
360
|
+
// Send real-time notification
|
|
361
|
+
await events.emit('notification.send', {
|
|
362
|
+
userId: user.userId,
|
|
363
|
+
type: 'info',
|
|
364
|
+
message: req.body.message,
|
|
365
|
+
timestamp: new Date(),
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
res.json({ sent: true });
|
|
369
|
+
});
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### **File Upload with Background Processing**
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import { storageClass } from '@bloomneo/appkit/storage';
|
|
376
|
+
import { queueClass } from '@bloomneo/appkit/queue';
|
|
377
|
+
import { loggerClass } from '@bloomneo/appkit/logger';
|
|
378
|
+
import { securityClass } from '@bloomneo/appkit/security';
|
|
379
|
+
|
|
380
|
+
const storage = storageClass.get();
|
|
381
|
+
const queue = queueClass.get();
|
|
382
|
+
const logger = loggerClass.get('upload');
|
|
383
|
+
const security = securityClass.get();
|
|
384
|
+
|
|
385
|
+
// File upload with background processing
|
|
386
|
+
app.post(
|
|
387
|
+
'/upload',
|
|
388
|
+
security.requests(10, 60000), // 10 uploads per minute
|
|
389
|
+
async (req, res) => {
|
|
390
|
+
// Sanitize filename
|
|
391
|
+
const safeName = security.input(req.file.originalname);
|
|
392
|
+
const key = `uploads/${Date.now()}-${safeName}`;
|
|
393
|
+
|
|
394
|
+
// Store file (auto-detects Local/S3/R2)
|
|
395
|
+
await storage.put(key, req.file.buffer, {
|
|
396
|
+
contentType: req.file.mimetype,
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Queue background processing
|
|
400
|
+
await queue.add('process-image', {
|
|
401
|
+
key,
|
|
402
|
+
userId: req.user.id,
|
|
403
|
+
originalName: req.file.originalname,
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
logger.info('File uploaded', { key, userId: req.user.id });
|
|
407
|
+
|
|
408
|
+
res.json({
|
|
409
|
+
url: storage.url(key),
|
|
410
|
+
key,
|
|
411
|
+
processing: true,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
// Background processing
|
|
417
|
+
queue.process('process-image', async (data) => {
|
|
418
|
+
const logger = loggerClass.get('processor');
|
|
419
|
+
|
|
420
|
+
try {
|
|
421
|
+
const buffer = await storage.get(data.key);
|
|
422
|
+
|
|
423
|
+
// Process image (resize, optimize, etc.)
|
|
424
|
+
const processed = await processImage(buffer);
|
|
425
|
+
|
|
426
|
+
// Store processed version
|
|
427
|
+
const processedKey = data.key.replace('.', '-processed.');
|
|
428
|
+
await storage.put(processedKey, processed);
|
|
429
|
+
|
|
430
|
+
logger.info('Image processed', {
|
|
431
|
+
original: data.key,
|
|
432
|
+
processed: processedKey,
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
return { processedKey };
|
|
436
|
+
} catch (error) {
|
|
437
|
+
logger.error('Processing failed', {
|
|
438
|
+
key: data.key,
|
|
439
|
+
error: error.message,
|
|
440
|
+
});
|
|
441
|
+
throw error;
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## ๐ค AI Agent Integration Examples
|
|
447
|
+
|
|
448
|
+
### **Prompt for Complete Auth System**
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
Create a Node.js API with user authentication, role-based access control,
|
|
452
|
+
and protected admin routes using Bloomneo AppKit.
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
**AI Agent Output** (guaranteed to work):
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
import { authClass } from '@bloomneo/appkit/auth';
|
|
459
|
+
import { errorClass } from '@bloomneo/appkit/error';
|
|
460
|
+
import { databaseClass } from '@bloomneo/appkit/database';
|
|
461
|
+
import { loggerClass } from '@bloomneo/appkit/logger';
|
|
462
|
+
|
|
463
|
+
const auth = authClass.get();
|
|
464
|
+
const error = errorClass.get();
|
|
465
|
+
const database = await databaseClass.get();
|
|
466
|
+
const logger = loggerClass.get('auth');
|
|
467
|
+
|
|
468
|
+
// Login endpoint
|
|
469
|
+
app.post(
|
|
470
|
+
'/auth/login',
|
|
471
|
+
error.asyncRoute(async (req, res) => {
|
|
472
|
+
const { email, password } = req.body;
|
|
473
|
+
|
|
474
|
+
if (!email || !password) {
|
|
475
|
+
throw error.badRequest('Email and password required');
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const user = await database.user.findUnique({ where: { email } });
|
|
479
|
+
if (!user) {
|
|
480
|
+
throw error.unauthorized('Invalid credentials');
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const isValid = await auth.comparePassword(password, user.password);
|
|
484
|
+
if (!isValid) {
|
|
485
|
+
throw error.unauthorized('Invalid credentials');
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Generate login token for user authentication
|
|
489
|
+
const loginToken = auth.generateLoginToken({
|
|
490
|
+
userId: user.id,
|
|
491
|
+
role: user.role,
|
|
492
|
+
level: user.level,
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
logger.info('User logged in', { userId: user.id });
|
|
496
|
+
res.json({ token: loginToken, user: { id: user.id, email: user.email } });
|
|
497
|
+
})
|
|
498
|
+
);
|
|
499
|
+
|
|
500
|
+
// Create API token for external service
|
|
501
|
+
app.post(
|
|
502
|
+
'/admin/api-tokens',
|
|
503
|
+
auth.requireLoginToken(),
|
|
504
|
+
auth.requireUserRoles(['admin.tenant']),
|
|
505
|
+
error.asyncRoute(async (req, res) => {
|
|
506
|
+
const { keyId, permissions } = req.body;
|
|
507
|
+
|
|
508
|
+
// Generate API token for service authentication
|
|
509
|
+
const apiToken = auth.generateApiToken(
|
|
510
|
+
{
|
|
511
|
+
keyId,
|
|
512
|
+
role: 'service',
|
|
513
|
+
level: 'external',
|
|
514
|
+
permissions,
|
|
515
|
+
},
|
|
516
|
+
'1y'
|
|
517
|
+
);
|
|
518
|
+
|
|
519
|
+
res.json({ apiToken });
|
|
520
|
+
})
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
// Protected user route (requires login token)
|
|
524
|
+
app.get(
|
|
525
|
+
'/api/profile',
|
|
526
|
+
auth.requireLoginToken(),
|
|
527
|
+
error.asyncRoute(async (req, res) => {
|
|
528
|
+
const user = auth.user(req);
|
|
529
|
+
const profile = await database.user.findUnique({
|
|
530
|
+
where: { id: user.userId },
|
|
531
|
+
});
|
|
532
|
+
res.json(profile);
|
|
533
|
+
})
|
|
534
|
+
);
|
|
535
|
+
|
|
536
|
+
// Admin-only route (requires login token + admin role)
|
|
537
|
+
app.get(
|
|
538
|
+
'/api/admin/users',
|
|
539
|
+
auth.requireLoginToken(),
|
|
540
|
+
auth.requireUserRoles(['admin.tenant']),
|
|
541
|
+
error.asyncRoute(async (req, res) => {
|
|
542
|
+
const users = await database.user.findMany();
|
|
543
|
+
res.json(users);
|
|
544
|
+
})
|
|
545
|
+
);
|
|
546
|
+
|
|
547
|
+
// API endpoint (requires API token)
|
|
548
|
+
app.post(
|
|
549
|
+
'/webhook/data',
|
|
550
|
+
auth.requireApiToken(),
|
|
551
|
+
error.asyncRoute(async (req, res) => {
|
|
552
|
+
const token = auth.user(req);
|
|
553
|
+
logger.info('Webhook received', { keyId: token.keyId });
|
|
554
|
+
res.json({ received: true });
|
|
555
|
+
})
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
// Error handling middleware (must be last)
|
|
559
|
+
app.use(error.handleErrors());
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### **Prompt for Multi-Tenant Data API**
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
Build a multi-tenant API where users can only see their organization's data,
|
|
566
|
+
but admins can access all organizations.
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**AI Agent Output**:
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
import { databaseClass } from '@bloomneo/appkit/database';
|
|
573
|
+
import { authClass } from '@bloomneo/appkit/auth';
|
|
574
|
+
import { errorClass } from '@bloomneo/appkit/error';
|
|
575
|
+
|
|
576
|
+
const auth = authClass.get();
|
|
577
|
+
const error = errorClass.get();
|
|
578
|
+
|
|
579
|
+
// User data (tenant-isolated)
|
|
580
|
+
app.get(
|
|
581
|
+
'/api/projects',
|
|
582
|
+
auth.requireLogin(),
|
|
583
|
+
error.asyncRoute(async (req, res) => {
|
|
584
|
+
const database = await databaseClass.get(); // Auto-filtered by user's tenant
|
|
585
|
+
const projects = await database.project.findMany({
|
|
586
|
+
include: { tasks: true },
|
|
587
|
+
});
|
|
588
|
+
res.json(projects); // Only current tenant's projects
|
|
589
|
+
})
|
|
590
|
+
);
|
|
591
|
+
|
|
592
|
+
// Admin data (cross-tenant)
|
|
593
|
+
app.get(
|
|
594
|
+
'/api/admin/all-projects',
|
|
595
|
+
auth.requireRole('admin.system'),
|
|
596
|
+
error.asyncRoute(async (req, res) => {
|
|
597
|
+
const dbTenants = await databaseClass.getTenants(); // All tenants
|
|
598
|
+
const allProjects = await dbTenants.project.findMany({
|
|
599
|
+
include: {
|
|
600
|
+
tasks: true,
|
|
601
|
+
_count: { select: { tasks: true } },
|
|
602
|
+
},
|
|
603
|
+
});
|
|
604
|
+
res.json(allProjects); // All organizations' projects
|
|
605
|
+
})
|
|
606
|
+
);
|
|
607
|
+
|
|
608
|
+
// Organization-specific admin access
|
|
609
|
+
app.get(
|
|
610
|
+
'/api/admin/org/:orgId/projects',
|
|
611
|
+
auth.requireRole('admin.org'),
|
|
612
|
+
error.asyncRoute(async (req, res) => {
|
|
613
|
+
const { orgId } = req.params;
|
|
614
|
+
const orgDatabase = await databaseClass.org(orgId).get();
|
|
615
|
+
const projects = await orgDatabase.project.findMany();
|
|
616
|
+
res.json(projects); // Specific organization's projects
|
|
617
|
+
})
|
|
618
|
+
);
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
## ๐ Production Deployment
|
|
622
|
+
|
|
623
|
+
### **Required Environment Variables**
|
|
624
|
+
|
|
625
|
+
```bash
|
|
626
|
+
# Core Security (Required)
|
|
627
|
+
VOILA_AUTH_SECRET=your-super-secure-jwt-secret-minimum-32-chars
|
|
628
|
+
|
|
629
|
+
# Database (Required)
|
|
630
|
+
DATABASE_URL=postgresql://user:pass@host:5432/database
|
|
631
|
+
|
|
632
|
+
# Production Services (Auto-detected)
|
|
633
|
+
REDIS_URL=redis://user:pass@host:6379
|
|
634
|
+
AWS_S3_BUCKET=your-bucket
|
|
635
|
+
RESEND_API_KEY=re_your_api_key
|
|
636
|
+
VOILA_SECURITY_CSRF_SECRET=your-csrf-secret-32-chars
|
|
637
|
+
|
|
638
|
+
# Multi-tenancy (Optional)
|
|
639
|
+
VOILA_DB_TENANT=auto
|
|
640
|
+
|
|
641
|
+
# Organization Scaling (Optional)
|
|
642
|
+
ORG_ACME=postgresql://acme.dedicated.aws.com/prod
|
|
643
|
+
ORG_STARTUP=mongodb://startup.azure.com/db
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
### **Docker Production Setup**
|
|
647
|
+
|
|
648
|
+
```dockerfile
|
|
649
|
+
FROM node:18-alpine
|
|
650
|
+
WORKDIR /app
|
|
651
|
+
|
|
652
|
+
# Copy package files
|
|
653
|
+
COPY package*.json ./
|
|
654
|
+
RUN npm ci --only=production
|
|
655
|
+
|
|
656
|
+
# Copy application
|
|
657
|
+
COPY . .
|
|
658
|
+
|
|
659
|
+
# Health check
|
|
660
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
661
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
|
|
662
|
+
|
|
663
|
+
EXPOSE 3000
|
|
664
|
+
CMD ["node", "server.js"]
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
### **Kubernetes Deployment**
|
|
668
|
+
|
|
669
|
+
```yaml
|
|
670
|
+
apiVersion: apps/v1
|
|
671
|
+
kind: Deployment
|
|
672
|
+
metadata:
|
|
673
|
+
name: voila-app
|
|
674
|
+
spec:
|
|
675
|
+
replicas: 3
|
|
676
|
+
selector:
|
|
677
|
+
matchLabels:
|
|
678
|
+
app: voila-app
|
|
679
|
+
template:
|
|
680
|
+
metadata:
|
|
681
|
+
labels:
|
|
682
|
+
app: voila-app
|
|
683
|
+
spec:
|
|
684
|
+
containers:
|
|
685
|
+
- name: app
|
|
686
|
+
image: my-app:latest
|
|
687
|
+
ports:
|
|
688
|
+
- containerPort: 3000
|
|
689
|
+
env:
|
|
690
|
+
- name: DATABASE_URL
|
|
691
|
+
valueFrom:
|
|
692
|
+
secretKeyRef:
|
|
693
|
+
name: app-secrets
|
|
694
|
+
key: database-url
|
|
695
|
+
- name: REDIS_URL
|
|
696
|
+
valueFrom:
|
|
697
|
+
secretKeyRef:
|
|
698
|
+
name: app-secrets
|
|
699
|
+
key: redis-url
|
|
700
|
+
livenessProbe:
|
|
701
|
+
httpGet:
|
|
702
|
+
path: /health
|
|
703
|
+
port: 3000
|
|
704
|
+
initialDelaySeconds: 30
|
|
705
|
+
periodSeconds: 10
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
## ๐ Performance & Scalability
|
|
709
|
+
|
|
710
|
+
### **Benchmarks**
|
|
711
|
+
|
|
712
|
+
- **Startup Time**: < 100ms (all modules loaded)
|
|
713
|
+
- **Memory Usage**: < 50MB baseline (production)
|
|
714
|
+
- **Request Throughput**: 10,000+ req/sec (with Redis)
|
|
715
|
+
- **Database Connections**: Automatic pooling and management
|
|
716
|
+
|
|
717
|
+
### **Scaling Characteristics**
|
|
718
|
+
|
|
719
|
+
| Environment | Cache | Storage | Queue | Database |
|
|
720
|
+
| --------------- | ------------- | ----------- | ------------- | ------------- |
|
|
721
|
+
| **Development** | Memory | Local | Memory | Single |
|
|
722
|
+
| **Staging** | Redis | S3 | Redis | Single |
|
|
723
|
+
| **Production** | Redis Cluster | S3/R2 + CDN | Redis Cluster | Read Replicas |
|
|
724
|
+
| **Enterprise** | Multi-region | Multi-cloud | Distributed | Multi-tenant |
|
|
725
|
+
|
|
726
|
+
## ๐งช Testing & Quality
|
|
727
|
+
|
|
728
|
+
### **Testing Setup**
|
|
729
|
+
|
|
730
|
+
```typescript
|
|
731
|
+
import { utilClass } from '@bloomneo/appkit/util';
|
|
732
|
+
import { loggerClass } from '@bloomneo/appkit/logger';
|
|
733
|
+
import { cacheClass } from '@bloomneo/appkit/cache';
|
|
734
|
+
import { databaseClass } from '@bloomneo/appkit/database';
|
|
735
|
+
import { authClass } from '@bloomneo/appkit/auth';
|
|
736
|
+
|
|
737
|
+
describe('API Tests', () => {
|
|
738
|
+
beforeEach(() => {
|
|
739
|
+
// Reset modules for clean tests
|
|
740
|
+
utilClass.clearCache();
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
afterEach(async () => {
|
|
744
|
+
// Clean up resources
|
|
745
|
+
await loggerClass.clear();
|
|
746
|
+
await cacheClass.clear();
|
|
747
|
+
await databaseClass.clear();
|
|
748
|
+
});
|
|
749
|
+
|
|
750
|
+
test('should handle user creation safely', async () => {
|
|
751
|
+
const auth = authClass.get();
|
|
752
|
+
const util = utilClass.get();
|
|
753
|
+
|
|
754
|
+
const userData = {
|
|
755
|
+
email: 'test@example.com',
|
|
756
|
+
name: 'Test User',
|
|
757
|
+
};
|
|
758
|
+
|
|
759
|
+
// Test safe property access
|
|
760
|
+
const email = util.get(userData, 'email');
|
|
761
|
+
expect(email).toBe('test@example.com');
|
|
762
|
+
|
|
763
|
+
// Test JWT token creation
|
|
764
|
+
const token = auth.signToken({
|
|
765
|
+
userId: 123,
|
|
766
|
+
role: 'user',
|
|
767
|
+
level: 'basic',
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
expect(token).toBeDefined();
|
|
771
|
+
|
|
772
|
+
// Test token verification
|
|
773
|
+
const payload = auth.verifyToken(token);
|
|
774
|
+
expect(payload.userId).toBe(123);
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### **Code Quality Standards**
|
|
780
|
+
|
|
781
|
+
- **100% TypeScript**: Full type safety across all modules
|
|
782
|
+
- **Comprehensive Tests**: Unit, integration, and e2e testing
|
|
783
|
+
- **Security Audits**: Regular dependency and vulnerability scanning
|
|
784
|
+
- **Performance Monitoring**: Built-in metrics and observability
|
|
785
|
+
|
|
786
|
+
## ๐ SEO & Discovery
|
|
787
|
+
|
|
788
|
+
### **Keywords & Technologies**
|
|
789
|
+
|
|
790
|
+
- **Node.js Framework**: Enterprise-grade backend development
|
|
791
|
+
- **AI Code Generation**: LLM-optimized, agentic programming
|
|
792
|
+
- **Multi-tenant SaaS**: Progressive scaling, organization management
|
|
793
|
+
- **Zero Configuration**: Environment-driven, production-ready
|
|
794
|
+
- **TypeScript Ready**: Full type safety, modern development
|
|
795
|
+
- **Microservices**: Modular architecture, independent scaling
|
|
796
|
+
- **JWT Authentication**: Role-based access control, security
|
|
797
|
+
- **Real-time Applications**: WebSocket support, event-driven, pub/sub
|
|
798
|
+
- **Cloud Native**: Docker, Kubernetes, auto-scaling
|
|
799
|
+
- **Developer Experience**: Fast development, maintainable code
|
|
800
|
+
|
|
801
|
+
### **Use Cases**
|
|
802
|
+
|
|
803
|
+
- **SaaS Applications**: Multi-tenant, progressive scaling
|
|
804
|
+
- **API Backends**: RESTful, GraphQL, real-time
|
|
805
|
+
- **E-commerce Platforms**: Payments, inventory, user management
|
|
806
|
+
- **Content Management**: File handling, media processing
|
|
807
|
+
- **Enterprise Applications**: Security, compliance, audit trails
|
|
808
|
+
- **Microservices**: Independent, scalable, maintainable
|
|
809
|
+
- **AI Applications**: LLM integration, automated workflows
|
|
810
|
+
- **Startup MVPs**: Rapid development, production-ready
|
|
811
|
+
|
|
812
|
+
## ๐ Learning Resources
|
|
813
|
+
|
|
814
|
+
### **Quick References**
|
|
815
|
+
|
|
816
|
+
- [๐ CLI Reference](docs/APPKIT_CLI.md) - Complete command guide and usage
|
|
817
|
+
examples
|
|
818
|
+
- [๐ค LLM Integration Guide](docs/APPKIT_LLM_GUIDE.md) - AI development patterns
|
|
819
|
+
and module usage
|
|
820
|
+
- [๐ Code Standards](docs/APPKIT_COMMENTS_GUIDELINES.md) - Documentation
|
|
821
|
+
guidelines for backend apps
|
|
822
|
+
|
|
823
|
+
### **Module Documentation**
|
|
824
|
+
|
|
825
|
+
- [Authentication & Authorization](/src/auth/README.md) - Dual token system,
|
|
826
|
+
role.level hierarchy, automatic inheritance
|
|
827
|
+
- [Database & Multi-tenancy](/src/database/README.md) - Progressive scaling,
|
|
828
|
+
organizations
|
|
829
|
+
- [File Storage & CDN](/src/storage/README.md) - Local to cloud, automatic
|
|
830
|
+
optimization
|
|
831
|
+
- [Caching & Performance](/src/cache/README.md) - Memory to Redis, namespace
|
|
832
|
+
isolation
|
|
833
|
+
- [Background Jobs](/src/queue/README.md) - Processing, scheduling, reliability
|
|
834
|
+
- [Email & Communications](/src/email/README.md) - Multi-provider, templates
|
|
835
|
+
- [Real-time Events](/src/event/README.md) - WebSocket, pub/sub, notifications
|
|
836
|
+
- [Security & Compliance](/src/security/README.md) - CSRF, encryption, rate
|
|
837
|
+
limiting
|
|
838
|
+
- [Error Handling](/src/error/README.md) - HTTP status codes, semantic errors
|
|
839
|
+
- [Logging & Observability](/src/logger/README.md) - Structured, multi-transport
|
|
840
|
+
- [Configuration Management](/src/config/README.md) - Environment-driven,
|
|
841
|
+
type-safe
|
|
842
|
+
- [Utilities & Helpers](/src/util/README.md) - 12 essential developer tools
|
|
843
|
+
|
|
844
|
+
## ๐ Community & Support
|
|
845
|
+
|
|
846
|
+
### **Getting Help**
|
|
847
|
+
|
|
848
|
+
- ๐ [GitHub Issues](https://github.com/bloomneo/appkit/issues) - Bug reports
|
|
849
|
+
and feature requests
|
|
850
|
+
- ๐ง [Email Support](mailto:kt@voilacode.com) - Direct support for enterprises
|
|
851
|
+
|
|
852
|
+
### **Contributing**
|
|
853
|
+
|
|
854
|
+
We welcome contributions! See our [Contributing Guide](CONTRIBUTING.md) for:
|
|
855
|
+
|
|
856
|
+
- ๐ Bug fixes and improvements
|
|
857
|
+
- ๐ Documentation enhancements
|
|
858
|
+
- โจ New module features
|
|
859
|
+
- ๐งช Test coverage improvements
|
|
860
|
+
- ๐ก Feature suggestions
|
|
861
|
+
|
|
862
|
+
<a id="scope-change"></a>
|
|
863
|
+
|
|
864
|
+
## ๐ Scope change (1.2.9)
|
|
865
|
+
|
|
866
|
+
This package was previously published as **`@voilajsx/appkit`**. Starting with `1.2.9` it lives at **`@bloomneo/appkit`**. The old package on npm is frozen at `1.2.8` and will not receive further updates.
|
|
867
|
+
|
|
868
|
+
**Migration:**
|
|
869
|
+
|
|
870
|
+
```diff
|
|
871
|
+
- npm install @voilajsx/appkit
|
|
872
|
+
+ npm install @bloomneo/appkit
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
```diff
|
|
876
|
+
- import { authClass } from '@voilajsx/appkit/auth';
|
|
877
|
+
+ import { authClass } from '@bloomneo/appkit/auth';
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
A project-wide find-and-replace of `@voilajsx/appkit` โ `@bloomneo/appkit` is sufficient. The API surface, props, types, and behavior are identical between the two scopes โ only the namespace changed.
|
|
881
|
+
|
|
882
|
+
## ๐ License
|
|
883
|
+
|
|
884
|
+
MIT ยฉ [Bloomneo](https://github.com/bloomneo) โ See [LICENSE](LICENSE) for
|
|
885
|
+
details.
|
|
886
|
+
|
|
887
|
+
---
|
|
888
|
+
|
|
889
|
+
<p align="center">
|
|
890
|
+
<strong>๐ Built for the AI-first future of software development</strong><br>
|
|
891
|
+
<strong>Where enterprise applications are generated, not written</strong><br><br>
|
|
892
|
+
<a href="https://github.com/bloomneo/appkit">โญ Star us on GitHub</a>
|
|
893
|
+
</p>
|
|
894
|
+
|
|
895
|
+
---
|
|
896
|
+
|
|
897
|
+
### **๐ Tags**
|
|
898
|
+
|
|
899
|
+
`nodejs` `typescript` `framework` `ai-ready` `enterprise` `multi-tenant` `saas`
|
|
900
|
+
`microservices` `jwt-authentication` `zero-config` `production-ready`
|
|
901
|
+
`agentic-ai` `llm-optimized` `progressive-scaling` `real-time` `websocket`
|
|
902
|
+
`pub-sub` `developer-experience`
|