Files
microdao-daarion/backend/services/dao-factory/dao-factory.service.ts
Apple 3de3c8cb36 feat: Add presence heartbeat for Matrix online status
- matrix-gateway: POST /internal/matrix/presence/online endpoint
- usePresenceHeartbeat hook with activity tracking
- Auto away after 5 min inactivity
- Offline on page close/visibility change
- Integrated in MatrixChatRoom component
2025-11-27 00:19:40 -08:00

111 lines
3.0 KiB
TypeScript

/**
* DAOFactory Service (MVP)
* Based on: core-services-mvp.md
*
* Responsibilities:
* - Create new DAO (A3/A4)
* - Create platforms (A2)
* - Validate input
* - Call PDP for access checks
* - Write DAO to Registry
*/
import type { CreateDaoInput, CreatePlatformInput } from '../../domain/dao/types';
import { pdpService } from '../pdp/pdp.service';
import { walletService } from '../wallet/wallet.service';
import { registryService } from '../registry/registry.service';
export class DaoFactoryService {
/**
* Create a new MicroDAO (A3 or A4)
* Requires: 1 DAARION on balance (not staked)
*/
async createDao(userId: string, input: CreateDaoInput): Promise<{ daoId: string }> {
// 1. Check wallet balance - need 1 DAARION on balance
const hasEnough = await walletService.hasEnoughForMicroDaoCreate(userId);
if (!hasEnough) {
throw new Error('INSUFFICIENT_BALANCE: Need 1 DAARION on balance to create MicroDAO');
}
// 2. Check PDP policy
const pdpResult = await pdpService.check(
'policy.dao.create',
{ type: 'dao' },
{ userId, daoLevel: input.level }
);
if (pdpResult.decision !== 'allow') {
throw new Error(`ACCESS_DENIED: ${pdpResult.reason || 'PDP denied'}`);
}
// 3. Create DAO record
const daoId = this.generateDaoId();
const daoRecord = {
daoId,
name: input.name,
description: input.description,
level: input.level,
type: input.type,
parentDaoId: null,
federationMode: 'none' as const,
createdAt: new Date().toISOString(),
};
// 4. Save to Registry
await registryService.saveDao(daoRecord);
return { daoId };
}
/**
* Create a new platform (A2)
*/
async createPlatform(userId: string, input: CreatePlatformInput): Promise<{ daoId: string }> {
// 1. Check wallet balance
const hasEnough = await walletService.hasEnoughForPlatformCreate(userId);
if (!hasEnough) {
throw new Error('INSUFFICIENT_BALANCE: Need 1 DAARION staked');
}
// 2. Check PDP policy
const pdpResult = await pdpService.check(
'policy.platform.create',
{ type: 'platform' },
{ userId, daoLevel: 'A2' }
);
if (pdpResult.decision !== 'allow') {
throw new Error(`ACCESS_DENIED: ${pdpResult.reason || 'PDP denied'}`);
}
// 3. Create platform record
const daoId = this.generateDaoId();
const daoRecord = {
daoId,
name: input.name,
description: input.description,
level: 'A2' as const,
type: 'platform' as const,
parentDaoId: null,
federationMode: 'none' as const,
createdAt: new Date().toISOString(),
};
// 4. Save to Registry
await registryService.saveDao(daoRecord);
return { daoId };
}
private generateDaoId(): string {
// MVP: Simple UUID-like generation
// TODO: Use proper UUID library
return `dao_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
}
// Singleton instance
export const daoFactoryService = new DaoFactoryService();