feat: implement Phase 1 Foundation for AutoScheduler GTD System
- Initialize npm workspaces monorepo (backend, frontend, shared-types) - Scaffold NestJS backend with modules: Auth, Users, Tasks, Projects, Inbox, Health - Create React frontend with Vite, TailwindCSS, Radix UI - Implement TypeORM entities: User, InboxItem, Task, Project - Add JWT authentication with Passport.js and bcrypt - Build Inbox capture API (POST /inbox, GET /inbox, POST /inbox/:id/process) - Create Inbox UI with quick-add form and GTD processing workflow modal - Configure Docker Compose stack (postgres, redis, backend, frontend) - Add health check endpoint with database/Redis status - Write unit tests for auth and inbox services Phase 1 features complete: - GTD Inbox Capture: Manual tasks via web form quick-add - GTD Processing Workflow: Interactive inbox processing interface Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
99
packages/frontend/src/lib/api.ts
Normal file
99
packages/frontend/src/lib/api.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import axios from 'axios';
|
||||
import { useAuthStore } from '../store/auth';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: '/api/v1',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = useAuthStore.getState().token;
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response?.status === 401) {
|
||||
useAuthStore.getState().logout();
|
||||
window.location.href = '/login';
|
||||
}
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
|
||||
export { api };
|
||||
|
||||
// Auth API
|
||||
export const authApi = {
|
||||
register: (data: { email: string; password: string; name: string; timezone: string }) =>
|
||||
api.post('/auth/register', data),
|
||||
login: (data: { email: string; password: string }) => api.post('/auth/login', data),
|
||||
logout: () => api.post('/auth/logout'),
|
||||
};
|
||||
|
||||
// Inbox API
|
||||
export const inboxApi = {
|
||||
getAll: () => api.get('/inbox'),
|
||||
create: (content: string) => api.post('/inbox', { content }),
|
||||
process: (
|
||||
id: string,
|
||||
data: {
|
||||
action: string;
|
||||
title?: string;
|
||||
context?: string;
|
||||
domain?: string;
|
||||
priority?: number;
|
||||
},
|
||||
) => api.post(`/inbox/${id}/process`, data),
|
||||
delete: (id: string) => api.delete(`/inbox/${id}`),
|
||||
};
|
||||
|
||||
// Tasks API
|
||||
export const tasksApi = {
|
||||
getAll: (params?: { status?: string; context?: string; domain?: string }) =>
|
||||
api.get('/tasks', { params }),
|
||||
getOne: (id: string) => api.get(`/tasks/${id}`),
|
||||
create: (data: {
|
||||
title: string;
|
||||
domain: string;
|
||||
context?: string;
|
||||
priority?: number;
|
||||
estimatedDuration?: number;
|
||||
dueDate?: string;
|
||||
projectId?: string;
|
||||
notes?: string;
|
||||
status?: string;
|
||||
}) => api.post('/tasks', data),
|
||||
update: (id: string, data: Record<string, unknown>) => api.patch(`/tasks/${id}`, data),
|
||||
delete: (id: string) => api.delete(`/tasks/${id}`),
|
||||
lock: (id: string) => api.post(`/tasks/${id}/lock`),
|
||||
unlock: (id: string) => api.post(`/tasks/${id}/unlock`),
|
||||
};
|
||||
|
||||
// Projects API
|
||||
export const projectsApi = {
|
||||
getAll: (params?: { status?: string; domain?: string }) => api.get('/projects', { params }),
|
||||
getOne: (id: string) => api.get(`/projects/${id}`),
|
||||
getTasks: (id: string) => api.get(`/projects/${id}/tasks`),
|
||||
create: (data: {
|
||||
name: string;
|
||||
domain: string;
|
||||
description?: string;
|
||||
desiredOutcome?: string;
|
||||
}) => api.post('/projects', data),
|
||||
update: (id: string, data: Record<string, unknown>) => api.patch(`/projects/${id}`, data),
|
||||
delete: (id: string) => api.delete(`/projects/${id}`),
|
||||
};
|
||||
|
||||
// User API
|
||||
export const userApi = {
|
||||
getMe: () => api.get('/users/me'),
|
||||
getPreferences: () => api.get('/users/preferences'),
|
||||
updatePreferences: (data: Record<string, unknown>) => api.patch('/users/preferences', data),
|
||||
};
|
||||
Reference in New Issue
Block a user