102 lines
3.4 KiB
TypeScript
102 lines
3.4 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import { randomUUID } from 'crypto';
|
|
|
|
const DATA_DIR = path.join(__dirname, '..', '..', 'build', 'data', 'db');
|
|
if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
|
|
export interface Group {
|
|
id: string;
|
|
name: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface GroupMember {
|
|
id: string;
|
|
group_id: string;
|
|
member_type: 'user' | 'group';
|
|
member_id: string;
|
|
}
|
|
|
|
export interface Project {
|
|
id: string;
|
|
name: string;
|
|
owner_id: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface ProjectMember {
|
|
id: string;
|
|
project_id: string;
|
|
member_type: 'user' | 'group';
|
|
member_id: string;
|
|
role: string;
|
|
}
|
|
|
|
function read<T>(table: string): T[] {
|
|
const file = path.join(DATA_DIR, `${table}.json`);
|
|
if (!fs.existsSync(file)) return [];
|
|
return JSON.parse(fs.readFileSync(file, 'utf8')) as T[];
|
|
}
|
|
|
|
function write<T>(table: string, rows: T[]): void {
|
|
fs.writeFileSync(path.join(DATA_DIR, `${table}.json`), JSON.stringify(rows, null, 2));
|
|
}
|
|
|
|
export const groups = {
|
|
all: (): Group[] => read<Group>('groups'),
|
|
findById: (id: string): Group | undefined => read<Group>('groups').find(g => g.id === id),
|
|
create(data: Omit<Group, 'id' | 'created_at'>): Group {
|
|
const rows = read<Group>('groups');
|
|
if (rows.find(g => g.name === data.name)) throw new Error('Taken');
|
|
const group: Group = { id: randomUUID(), ...data, created_at: new Date().toISOString() };
|
|
write('groups', [...rows, group]);
|
|
return group;
|
|
},
|
|
delete(id: string): void {
|
|
write('groups', read<Group>('groups').filter(g => g.id !== id));
|
|
write('group_members', read<GroupMember>('group_members').filter(m => m.group_id !== id));
|
|
}
|
|
};
|
|
|
|
export const groupMembers = {
|
|
forGroup: (groupId: string): GroupMember[] => read<GroupMember>('group_members').filter(m => m.group_id === groupId),
|
|
add(data: Omit<GroupMember, 'id'>): GroupMember {
|
|
const rows = read<GroupMember>('group_members');
|
|
const member: GroupMember = { id: randomUUID(), ...data };
|
|
write('group_members', [...rows, member]);
|
|
return member;
|
|
},
|
|
remove(id: string): void {
|
|
write('group_members', read<GroupMember>('group_members').filter(m => m.id !== id));
|
|
}
|
|
};
|
|
|
|
export const projects = {
|
|
all: (): Project[] => read<Project>('projects'),
|
|
findById: (id: string): Project | undefined => read<Project>('projects').find(p => p.id === id),
|
|
create(data: Omit<Project, 'id' | 'created_at'>): Project {
|
|
const rows = read<Project>('projects');
|
|
const project: Project = { id: randomUUID(), ...data, created_at: new Date().toISOString() };
|
|
write('projects', [...rows, project]);
|
|
return project;
|
|
},
|
|
delete(id: string): void {
|
|
write('projects', read<Project>('projects').filter(p => p.id !== id));
|
|
write('project_members', read<ProjectMember>('project_members').filter(m => m.project_id !== id));
|
|
}
|
|
};
|
|
|
|
export const projectMembers = {
|
|
forProject: (projectId: string): ProjectMember[] => read<ProjectMember>('project_members').filter(m => m.project_id === projectId),
|
|
add(data: Omit<ProjectMember, 'id'>): ProjectMember {
|
|
const rows = read<ProjectMember>('project_members');
|
|
const member: ProjectMember = { id: randomUUID(), ...data };
|
|
write('project_members', [...rows, member]);
|
|
return member;
|
|
},
|
|
remove(id: string): void {
|
|
write('project_members', read<ProjectMember>('project_members').filter(m => m.id !== id));
|
|
}
|
|
};
|