@ak-sara/fbao
v0.1.0
Published
Architectural Overlays for SvelteKit — FBA (Foundation-Business-Analytics) mental model
Maintainers
Readme
@ak-sara/fbao
Architectural Overlays for SvelteKit — a companion library implementing the FBA (Foundation-Business-Analytics) mental model for enterprise information system projects.
Stop rebuilding auth, database access, sessions, and utilities from scratch on every project. Install once, configure once, use everywhere.
Install
npx sv create my-app
cd my-app
bun add @ak-sara/fbaoSetup
Configure all modules once in src/lib/setup.ts:
import { configure } from '@ak-sara/fbao/foundation'
import { env } from '$env/static/private'
configure({
db: { url: env.DATABASE_URL },
auth: { mode: 'credentials' },
cache: { url: env.REDIS_URL },
})For MongoDB, inject the Db instance directly (avoids dual-bson issues with linked packages):
import { MongoClient } from 'mongodb'
import { setMongo } from '@ak-sara/fbao/foundation'
const client = new MongoClient(env.MONGODB_URI)
await client.connect()
setMongo(client.db('my_database'))The FBA Mental Model
| Block | Purpose | What you put here | |---|---|---| | Foundation | Infrastructure, no UI | DB, auth, sessions, email, logging | | Business | Domain features | CRUD pages, forms, workflows | | Analytics | Insight layer | Queries, dashboards, reports |
Import Guide — Browser-safe vs Server-only
@ak-sara/fbao/foundation is the main barrel. Never import it in Svelte components — it pulls in mongodb, argon2, bullmq, and other Node.js modules that crash browser bundles.
Rule of thumb:
.server.ts,+server.ts,lib/modules → use@ak-sara/fbao/foundation(or a granular subpath).sveltefiles → use only the granular subpaths marked ✅ below, or your own$lib/loggerwrapper
Granular subpaths
| Subpath | Browser-safe | Key exports |
|---|:---:|---|
| @ak-sara/fbao/foundation/config | ✅ | configure, getConfig, useConfig |
| @ak-sara/fbao/foundation/events | ✅ | defineEvent, useEvents |
| @ak-sara/fbao/foundation/privacy | ✅ | maskField, getMaskedRecord, getMaskedRecords |
| @ak-sara/fbao/foundation/sanitize | ✅ | escapeHtml, sanitizeObject, stripMongoOperators |
| @ak-sara/fbao/foundation/markdown | ✅ | parseMarkdown, extractTitle, generateTOC |
| @ak-sara/fbao/foundation/request | ✅ | request, RequestError |
| @ak-sara/fbao/foundation/logger | ⚠️ | useLogger (console-only in browser); file/db/loki/otlp transports are server-only |
| @ak-sara/fbao/foundation/auth | ❌ | PasswordService, OTPService, MongoSessionManager, JWT |
| @ak-sara/fbao/foundation/db | ❌ | Repository<T>, useDb, pagination helpers |
| @ak-sara/fbao/foundation/cache | ❌ | useCache (memory + Redis) |
| @ak-sara/fbao/foundation/queue | ❌ | useQueue, defineJob (BullMQ + memory) |
| @ak-sara/fbao/foundation/rateLimit | ❌ | RateLimiter, useRateLimit |
| @ak-sara/fbao/foundation/mailer | ❌ | sendEmail, EmailService |
| @ak-sara/fbao/foundation/sso | ❌ | useSso, OAuth2/OIDC providers |
| @ak-sara/fbao/foundation/trace | ❌ | trace, distributed tracing |
The ./foundation barrel also ships a browser condition — bundlers like Vite that respect the browser export condition will automatically get a safe subset. However, for bun-linked packages this condition may not be honored, so prefer explicit granular imports in browser contexts.
Blocks & Modules
Foundation Block
| Module | Description |
|---|---|
| config | Env validation, central registry |
| db | Database access — SQL (Drizzle) + MongoDB, Repository, serialization, pagination |
| auth | Sessions, RBAC, password hashing (Argon2), OTP, crypto, JWT |
| sso | OAuth2 / OIDC — Google, Microsoft, GitHub, custom OIDC |
| logger | Structured logging + MongoDB audit trail |
| cache | Redis / in-memory caching |
| queue | Background jobs — memory (zero deps) or BullMQ (Redis) |
| events | Internal typed pub/sub |
| request | Typed external API client |
| trace | Request tracing / correlation IDs |
| privacy | PII data masking — email, phone, KTP, date (UU PDP / GDPR) |
| mailer | Multi-provider email sending + domain validation |
| markdown | Markdown → HTML, title extraction, TOC generation |
Business Block
| Module | Description |
|---|---|
| api | SvelteKit route controller factory |
| datatable | <DataTable> — CRUD, filter, sort, paginate |
| form | <Form> — schema-driven, multi-step (Superforms + Zod) |
| dropdown | <Dropdown> — lazy, searchable |
| modal | <Modal> — confirm, alert, form variants |
| approval | <ApprovalFlow> — multi-stage workflow engine |
| upload | <Upload> — drag-drop, progress, preview |
| notify | <Toast> <Alert> — real-time notifications |
| search | <Search> — global and contextual |
| guard | <IfCan> — UI permission gate |
Analytics Block
| Module | Description |
|---|---|
| query | Flexible analytical query engine — core of Analytics |
| stream | Outbound data forwarding → Grafana, Wazuh, Prometheus, Loki |
| dashboard | <Dashboard> — widget grid, consumes query |
| chart | <Chart> — data visualization (ECharts) |
| report | Report template + renderer |
| export | useExport() — xlsx, pdf, csv (ExcelJS, PDFKit) |
| audit | Auto change-trail, hooks into db + stream |
| kpi | <KpiCard> — target vs actual metrics |
| filter | <FilterBuilder> — dynamic query composer |
Foundation Modules
Database (db)
MongoDB-first with SQL support via Drizzle ORM. Includes Repository pattern, serialization, and pagination helpers.
import {
useMongo, setMongo, Repository,
serializeObjectIds,
sanitizePaginationParams, buildSearchQuery, getMongoSort
} from '@ak-sara/fbao/foundation'
// Repository pattern
const users = new Repository(() => useMongo(), 'users')
const user = await users.findById(id)
const page = await users.paginate({ page: 1, limit: 20, filter: { active: true } })
// Serialize for SvelteKit load functions (ObjectId → string, Date → ISO)
return { data: serializeObjectIds(results) }
// Pagination helpers
const params = sanitizePaginationParams({ page: '2', pageSize: '25' })
const query = buildSearchQuery('john', ['name', 'email'])
const sort = getMongoSort('createdAt', 'desc')Authentication (auth)
Password hashing (Argon2), MongoDB session management, OTP, RBAC, crypto utilities, and JWT.
import {
PasswordService, MongoSessionManager, OTPService,
generateSecureToken, hashToken, createJwtService,
defineRole, can
} from '@ak-sara/fbao/foundation'
// Password hashing
const pwd = new PasswordService()
const hash = await pwd.hash('password123')
const valid = await pwd.verify(hash, 'password123')
// Session management (MongoDB-backed)
const sessions = new MongoSessionManager(() => getDB(), {
maxAge: 86400,
cookieName: 'session'
})
const { token, cookie } = await sessions.create(userId, cookies)
const session = await sessions.validate(token)
// OTP
const otp = new OTPService(() => getDB())
const code = await otp.generate(userId, 'email_verify')
const result = await otp.validate(userId, code, 'email_verify')
// JWT
const jwt = createJwtService({ secret: env.JWT_SECRET, issuer: 'my-app' })
const token = jwt.sign({ sub: userId }, '1h')
// Crypto helpers
const resetToken = generateSecureToken()
const hashed = hashToken(resetToken)Logging & Audit (logger)
Structured logging with MongoDB-backed audit trail.
import { useLogger, AuditLogger, extractRequestMeta } from '@ak-sara/fbao/foundation'
const log = useLogger({ module: 'auth' })
log.info('user logged in', { userId })
// Audit logging
const audit = new AuditLogger(() => getDB())
await audit.log({
action: 'identity.update',
userId, targetId,
changes: { before, after },
...extractRequestMeta(event)
})Privacy (privacy)
PII data masking for compliance (UU PDP, GDPR). Supports email, phone, KTP, date, and custom masking.
import { getMaskedRecord, getMaskedRecords, getDefaultMaskingConfig } from '@ak-sara/fbao/foundation'
const config = getDefaultMaskingConfig()
const masked = getMaskedRecord(employee, config, userRoles)
// employee.email → "u***@e***.com"
// employee.phone → "0812****7890"Mailer (mailer)
Multi-provider email sending (Gmail, Microsoft 365, SendGrid, SMTP) with domain validation.
import { sendEmail, isEmailDomainAllowed } from '@ak-sara/fbao/foundation'
await sendEmail({
provider: 'gmail',
config: { user: '[email protected]', appPassword: '...' },
to: '[email protected]',
subject: 'Welcome',
html: '<h1>Welcome!</h1>'
})
// Domain validation
isEmailDomainAllowed('[email protected]', ['*.co.id']) // trueMarkdown (markdown)
Parse markdown to HTML with heading IDs, extract titles, and generate table of contents.
import { parseMarkdown, extractTitle, generateTOC } from '@ak-sara/fbao/foundation'
const html = parseMarkdown(mdContent)
const title = extractTitle(mdContent) // First # heading
const toc = generateTOC(mdContent) // [{ level, text, id }]Tooling
Testing
Built-in zero-dependency test runner. No Jest or Vitest required.
import { test, expect, suite } from '@ak-sara/fbao/testing'
test('validates password', 'Should reject weak passwords', async () => {
const pwd = new PasswordService({ minLength: 8 })
const result = pwd.validateStrength('abc')
expect(result.valid).toBe(false)
})CLI: fba-test --dir ./tests --out test-results.csv
MCP (Model Context Protocol)
Built-in MCP server so AI agents understand @ak-sara/fbao without hallucinating.
Resources (AI reads these):
fba://overview— library overviewfba://modules/{block}— module list per blockfba://configure— configure() schema and examples
Tools (AI calls these):
list_modules— list modules, optionally by blockget_module— detailed info for a specific module
Connect to an AI agent:
{
"mcpServers": {
"fba": { "command": "npx", "args": ["fba-mcp"] }
}
}Requirements
- SvelteKit 2+
- Node 20+ / Bun
- MongoDB 6+ (for db, auth, sessions, audit modules)
Optional Peer Dependencies
Install only what you use:
| Package | Required by |
|---|---|
| @node-rs/argon2 | PasswordService |
| jsonwebtoken | createJwtService |
| nodemailer | sendEmail (Gmail, Microsoft 365, SMTP) |
| @sendgrid/mail | sendEmail (SendGrid provider) |
| marked | parseMarkdown, extractTitle, generateTOC |
License
MIT
