| name | axiodb-development |
| description | Core development rules and patterns for AxioDB embedded NoSQL database |
| version | 1.0.0 |
| tags | ["typescript","database","testing","build"] |
| author | AxioDB Team |
AxioDB Development Skill
Project Identity
AxioDB - Embedded NoSQL database for Node.js
- TypeScript strict mode → CommonJS
- Node.js ≥20.0.0
- Zero native dependencies
- Singleton pattern, file-per-document storage
Mandatory Workflows
After EVERY Code Change
npm run build
For ANY Feature Change
- Update tests in
Test/modules/
- Run
npm test - all tests must pass
- Update docs (README.md, Document/, Dockerfile)
- Run
npm run lint - must pass
Definition of "Done"
A task is NOT complete until ALL of these are true:
- ✅ Code written following standards
- ✅
npm run build passes with zero errors
- ✅ Tests added/updated in
Test/modules/
- ✅
npm test passes - all tests green
- ✅
npm run lint passes
- ✅ Documentation updated (README, Document/, Dockerfile)
- ✅ No breaking changes (or explicitly noted and approved)
- ✅ Self-reviewed for performance, security, maintainability
Architecture Constraints
Singleton Pattern (NON-NEGOTIABLE)
export class AxioDB {
private static _instance: AxioDB;
constructor() {
if (AxioDB._instance) {
throw new Error("Only one instance of AxioDB is allowed.");
}
AxioDB._instance = this;
}
}
Critical Implication: Tests MUST run in separate child processes. Cannot run tests in parallel.
File-Per-Document Storage
{RootPath}/{DatabaseName}/{CollectionName}/{documentId}.axiodb
Dual-Write Pattern (Indexes)
await this.indexCache.set(key, data, TTL);
await this.fileManager.writeFile(path, JSON.stringify(data));
Random Cache TTL (5-15 minutes)
const TTL = Math.floor(Math.random() * (15 - 5 + 1) + 5) * 60 * 1000;
Why: Prevents cache stampede/thundering herd
TypeScript Standards (STRICT)
NO any Types - EVER
const result: any = await operation();
interface OperationResult {
success: boolean;
data: DocumentData;
}
const result: OperationResult = await operation();
Strict Null Checks
function get(id: string): Document | null {
return this.cache.get(id) ?? null;
}
const doc = get('123');
if (doc !== null) {
console.log(doc.name);
}
SOLID Principles
Single Responsibility
Each class/module has ONE reason to change.
Don't Repeat Yourself (DRY)
If same logic appears in 2+ files, extract to Helper/ directory.
No Hacky Solutions
setTimeout(() => { }, 1000);
eval(userInput);
try { risky(); } catch (e) { }
await properAsyncOperation();
const sanitized = validateAndSanitize(userInput);
try { await risky(); } catch (error) {
logger.error('Operation failed', error);
return ResponseHelper.error('Failed', StatusCodes.ERROR);
}
Testing Requirements
Location
Test/modules/
├── crud.test.js # CRUD operations
├── transaction.test.js # Transactions, WAL, savepoints
└── read.test.js # Read optimizations, caching
Coverage Required
- Happy path (success scenarios)
- Edge cases (empty, null, undefined, large data)
- Error cases (validation failures, file errors, conflicts)
- Concurrent operations
- Backward compatibility
Module Organization
source/
├── Services/
│ ├── Database/ # Database ops
│ ├── Collection/ # Collection ops
│ ├── CRUD Operation/ # Create, Reader, Update, Delete
│ ├── Index/ # Index management (cache + disk)
│ ├── Aggregation/ # MongoDB-style pipelines
│ └── Transaction/ # ACID, WAL, sessions
├── engine/Filesystem/ # FileManager, FolderManager
├── server/ # HTTP GUI (Fastify, port 27018)
├── tcp/ # TCP server (AxioDBCloud, port 27019)
├── client/ # AxioDBCloud TCP client
├── Helper/ # Converter, Crypto, Response
└── Memory/ # InMemoryCache
Naming Conventions
- Files:
{Feature}.operation.ts, {Feature}.service.ts, {Feature}.helper.ts
- Classes: PascalCase:
FileManager, QueryMatcher
- Methods: camelCase:
createDatabase(), isValidDocument()
- Variables: camelCase:
documentId, collectionPath
Performance Standards
1. Use InMemoryCache
const cached = this.cache.get(key);
if (cached) return cached;
const data = await this.readFromDisk(id);
this.cache.set(key, data, TTL);
return data;
2. Batch Operations
await Promise.all(docs.map(d => this.insert(d)));
for (const d of docs) { await this.insert(d); }
3. Use Map for O(1) Lookups
const map = new Map<string, Document>();
const found = map.get(id);
const found = array.find(d => d.id === id);
Security Standards
1. Validate All Input
if (!document || typeof document !== 'object') {
return this.ResponseHelper.error('Invalid', StatusCodes.BAD_REQUEST);
}
if (Array.isArray(document)) {
return this.ResponseHelper.error('Cannot be array', StatusCodes.BAD_REQUEST);
}
2. Sanitize File Paths
const sanitized = documentId.replace(/[^a-zA-Z0-9-_]/g, '_');
return path.join(collectionPath, `${sanitized}.axiodb`);
3. Handle Sensitive Data
const users = await db.createCollection('Users', true, process.env.KEY);
logger.info('Auth', { userId });
logger.info('Auth', { password });
Documentation Requirements
Update when features change:
- README.md - Public API, features, quick start examples
- Document/ - React docs site (
cd Document && npm run dev)
- Dockerfile - If ports, env vars, or commands change
- JSDoc - All public methods with examples
Anti-Patterns (FORBIDDEN)
❌ Using any types
❌ Duplicated code (violates DRY)
❌ Sequential operations that could be parallel
❌ Ignoring build errors
❌ Skipping tests
❌ Missing documentation
❌ Hardcoded values
❌ Magic strings/numbers
❌ Deep nesting (>3 levels)
❌ Unclear variable names
❌ Suppressing errors without handling
Commands
npm run build
npm test
npm test crud
npm test transaction
npm test read
npm run lint
node Test/modules/crud.test.js
cd Document && npm run dev
Success Criteria
Every task must meet ALL:
- ✅ Builds successfully (
npm run build)
- ✅ Tests pass (
npm test)
- ✅ Lint passes (
npm run lint)
- ✅ Docs updated
- ✅ No regressions
- ✅ Follows patterns
- ✅ Security validated
- ✅ Performance acceptable