{"openapi":"3.0.0","paths":{"/api/v1/tracker/status":{"get":{"description":"Returns the currently running time entry with activities and tags, or `null` if nothing is being tracked.","operationId":"V1TrackerController_status","parameters":[],"responses":{"200":{"description":"Active entry or null"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `tracker:read`"}},"security":[{"bearer":[]}],"summary":"Get current active time entry","tags":["API v1 — Tracker"]}},"/api/v1/tracker/start":{"post":{"description":"Starts a new time entry. Optionally provide description and activities in one call. If activities are provided, the auto-created empty activity is replaced. Tags can be referenced by name or ID.","operationId":"V1TrackerController_start","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1TrackerStartDto"}}}},"responses":{"200":{"description":"Created entry with activities"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `tracker:write`"},"429":{"description":"Rate limit exceeded"}},"security":[{"bearer":[]}],"summary":"Start tracking time","tags":["API v1 — Tracker"]}},"/api/v1/tracker/stop":{"post":{"description":"Stops the active entry. Set `restart: true` to immediately start a new one (useful for switching tasks). When restarting, `activities` in the body are applied to the **new** entry.","operationId":"V1TrackerController_stop","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1TrackerStopDto"}}}},"responses":{"200":{"description":"Stopped entry and optional new entry"},"401":{"description":"Invalid or missing PAT token"}},"security":[{"bearer":[]}],"summary":"Stop current time entry","tags":["API v1 — Tracker"]}},"/api/v1/tracker/log":{"post":{"description":"Creates a finished time entry with explicit start/end times. Useful for logging work done without the tracker running.","operationId":"V1TrackerController_log","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1TrackerLogDto"}}}},"responses":{"200":{"description":"Created retroactive entry"}},"security":[{"bearer":[]}],"summary":"Log a completed time entry retroactively","tags":["API v1 — Tracker"]}},"/api/v1/tracker/history":{"get":{"description":"Returns time entries sorted by date descending. Filter by date range and/or tag (by name or ID).","operationId":"V1TrackerController_history","parameters":[{"name":"date_from","required":false,"in":"query","description":"Filter from date (ISO date)","schema":{"example":"2026-05-01","type":"string"}},{"name":"date_to","required":false,"in":"query","description":"Filter to date (ISO date)","schema":{"example":"2026-05-31","type":"string"}},{"name":"tag","required":false,"in":"query","description":"Filter by tag name or ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"limit","required":false,"in":"query","description":"Max entries to return","schema":{"default":50,"example":50,"type":"number"}}],"responses":{"200":{"description":"Paginated list of entries with total count"}},"security":[{"bearer":[]}],"summary":"List time entries","tags":["API v1 — Tracker"]}},"/api/v1/tracker/tags":{"get":{"description":"Returns all time tracker tags. Tags are used to categorize activities within time entries.","operationId":"V1TrackerController_tags","parameters":[],"responses":{"200":{"description":"List of tags"}},"security":[{"bearer":[]}],"summary":"List all tracker tags","tags":["API v1 — Tracker"]}},"/api/v1/tasks":{"get":{"description":"Returns tasks with optional filters. Streams and projects can be referenced by name or numeric ID.","operationId":"V1TasksController_list","parameters":[{"name":"stream","required":false,"in":"query","description":"Filter by stream name, key, or ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"project","required":false,"in":"query","description":"Filter by project name or ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"status","required":false,"in":"query","schema":{"example":"open","type":"string","enum":["open","in_progress","done","cancelled"]}},{"name":"priority","required":false,"in":"query","schema":{"example":"high","type":"string","enum":["low","medium","high","urgent"]}},{"name":"search","required":false,"in":"query","description":"Search in title","schema":{"example":"login","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Max results to return","schema":{"default":50,"example":50,"type":"number"}}],"responses":{"200":{"description":"Array of tasks"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `tasks:read`"}},"security":[{"bearer":[]}],"summary":"List tasks","tags":["API v1 — Tasks"]},"post":{"description":"Creates a new task. `stream` is required and can be a name, key (e.g. \"DEV\"), or numeric ID. `project` is optional and also accepts name or ID.","operationId":"V1TasksController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateTaskDto"}}}},"responses":{"201":{"description":"Created task"},"404":{"description":"Stream or project not found"}},"security":[{"bearer":[]}],"summary":"Create a task","tags":["API v1 — Tasks"]}},"/api/v1/tasks/{id}":{"get":{"operationId":"V1TasksController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":42,"type":"number"}}],"responses":{"200":{"description":"Task object"},"404":{"description":"Task not found"}},"security":[{"bearer":[]}],"summary":"Get task by ID","tags":["API v1 — Tasks"]},"patch":{"operationId":"V1TasksController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":42,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateTaskDto"}}}},"responses":{"200":{"description":"Updated task"},"404":{"description":"Task not found"}},"security":[{"bearer":[]}],"summary":"Update a task","tags":["API v1 — Tasks"]},"delete":{"operationId":"V1TasksController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":42,"type":"number"}}],"responses":{"200":{"description":"Task deleted"},"404":{"description":"Task not found"}},"security":[{"bearer":[]}],"summary":"Delete a task","tags":["API v1 — Tasks"]}},"/api/v1/tasks/{id}/complete":{"post":{"description":"Shortcut to set task status to `done`.","operationId":"V1TasksController_complete","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":42,"type":"number"}}],"responses":{"200":{"description":"Completed task"},"404":{"description":"Task not found"}},"security":[{"bearer":[]}],"summary":"Complete a task","tags":["API v1 — Tasks"]}},"/api/v1/projects":{"get":{"description":"Returns projects with optional stream and status filters. Stream can be referenced by name, key, or ID.","operationId":"V1ProjectsController_list","parameters":[{"name":"stream","required":false,"in":"query","description":"Filter by stream name, key, or ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"status","required":false,"in":"query","schema":{"example":"active","type":"string","enum":["active","paused","completed","cancelled"]}},{"name":"limit","required":false,"in":"query","schema":{"default":50,"example":50,"type":"number"}}],"responses":{"200":{"description":"Array of projects with tasks"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `projects:read`"}},"security":[{"bearer":[]}],"summary":"List projects","tags":["API v1 — Projects"]},"post":{"description":"`stream` is required and can be a name, key, or numeric ID.","operationId":"V1ProjectsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateProjectDto"}}}},"responses":{"201":{"description":"Created project"},"404":{"description":"Stream not found"}},"security":[{"bearer":[]}],"summary":"Create a project","tags":["API v1 — Projects"]}},"/api/v1/projects/{id}":{"get":{"operationId":"V1ProjectsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":5,"type":"number"}}],"responses":{"200":{"description":"Project object with tasks"},"404":{"description":"Project not found"}},"security":[{"bearer":[]}],"summary":"Get project by ID","tags":["API v1 — Projects"]},"patch":{"operationId":"V1ProjectsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":5,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateProjectDto"}}}},"responses":{"200":{"description":"Updated project"},"404":{"description":"Project not found"}},"security":[{"bearer":[]}],"summary":"Update a project","tags":["API v1 — Projects"]}},"/api/v1/streams":{"get":{"description":"Returns all active streams. Streams are top-level categories (e.g. \"Development\", \"Design\").","operationId":"V1StreamsController_list","parameters":[],"responses":{"200":{"description":"Array of streams"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `streams:read`"}},"security":[{"bearer":[]}],"summary":"List active streams","tags":["API v1 — Streams"]},"post":{"description":"`key` is a short code used in task IDs (e.g. key \"DEV\" produces tasks like DEV-1, DEV-2).","operationId":"V1StreamsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateStreamDto"}}}},"responses":{"201":{"description":"Created stream"}},"security":[{"bearer":[]}],"summary":"Create a stream","tags":["API v1 — Streams"]}},"/api/v1/streams/{id}":{"get":{"operationId":"V1StreamsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Stream object"},"404":{"description":"Stream not found"}},"security":[{"bearer":[]}],"summary":"Get stream by ID","tags":["API v1 — Streams"]},"patch":{"description":"Set `is_active: false` to archive a stream.","operationId":"V1StreamsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateStreamDto"}}}},"responses":{"200":{"description":"Updated stream"},"404":{"description":"Stream not found"}},"security":[{"bearer":[]}],"summary":"Update a stream","tags":["API v1 — Streams"]}},"/api/v1/notes":{"get":{"description":"Returns notes with optional filters by stream, project (by name or ID), and text search.","operationId":"V1NotesController_list","parameters":[{"name":"stream","required":false,"in":"query","description":"Filter by stream name, key, or ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"project","required":false,"in":"query","description":"Filter by project name or ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"search","required":false,"in":"query","description":"Search in title and content","schema":{"example":"roadmap","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Max results to return","schema":{"default":50,"example":50,"type":"number"}}],"responses":{"200":{"description":"Array of notes"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `notes:read`"}},"security":[{"bearer":[]}],"summary":"List notes","tags":["API v1 — Notes"]},"post":{"description":"Stream and project can be referenced by name or numeric ID. Link to a task via `issue_id`.","operationId":"V1NotesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateNoteDto"}}}},"responses":{"201":{"description":"Created note"},"404":{"description":"Stream or project not found"}},"security":[{"bearer":[]}],"summary":"Create a note","tags":["API v1 — Notes"]}},"/api/v1/notes/{id}":{"get":{"operationId":"V1NotesController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":10,"type":"number"}}],"responses":{"200":{"description":"Note object"},"404":{"description":"Note not found"}},"security":[{"bearer":[]}],"summary":"Get note by ID","tags":["API v1 — Notes"]},"patch":{"operationId":"V1NotesController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":10,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateNoteDto"}}}},"responses":{"200":{"description":"Updated note"},"404":{"description":"Note not found"}},"security":[{"bearer":[]}],"summary":"Update a note","tags":["API v1 — Notes"]},"delete":{"operationId":"V1NotesController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":10,"type":"number"}}],"responses":{"200":{"description":"Note deleted"},"404":{"description":"Note not found"}},"security":[{"bearer":[]}],"summary":"Delete a note","tags":["API v1 — Notes"]}},"/api/v1/notes/{id}/archive":{"post":{"operationId":"V1NotesController_archive","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":10,"type":"number"}}],"responses":{"200":{"description":"Archived note"},"404":{"description":"Note not found"}},"security":[{"bearer":[]}],"summary":"Archive a note","tags":["API v1 — Notes"]}},"/api/v1/profile":{"get":{"description":"Returns basic profile info and the list of all available API scopes. Useful for checking who the token belongs to.","operationId":"V1ProfileController_get","parameters":[],"responses":{"200":{"description":"User profile","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"number","example":1},"username":{"type":"string","example":"artem"},"name":{"type":"string","example":"Artem","nullable":true},"last_name":{"type":"string","example":"Romanchuk","nullable":true},"email":{"type":"string","example":"user@example.com"},"available_scopes":{"type":"array","items":{"type":"string"},"example":["tracker:read","tracker:write"]}}}}}},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `profile:read`"}},"security":[{"bearer":[]}],"summary":"Get current user profile","tags":["API v1 — Profile"]}},"/api/v1/events":{"get":{"description":"Returns events within the specified date range. If no range is given, returns all events. Hidden calendars are automatically filtered out.","operationId":"V1EventsController_list","parameters":[{"name":"start","required":false,"in":"query","description":"Range start (ISO date)","schema":{"example":"2026-05-01T00:00:00.000Z","type":"string"}},{"name":"end","required":false,"in":"query","description":"Range end (ISO date)","schema":{"example":"2026-05-31T23:59:59.000Z","type":"string"}}],"responses":{"200":{"description":"Array of calendar events"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `events:read`"}},"security":[{"bearer":[]}],"summary":"List calendar events","tags":["API v1 — Events"]},"post":{"description":"Creates a single (non-recurring) event. If `calendar_id` is not provided, the default calendar is used.","operationId":"V1EventsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateEventDto"}}}},"responses":{"201":{"description":"Created event"},"404":{"description":"Calendar not found"}},"security":[{"bearer":[]}],"summary":"Create a calendar event","tags":["API v1 — Events"]}},"/api/v1/events/{id}":{"get":{"operationId":"V1EventsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":15,"type":"number"}}],"responses":{"200":{"description":"Event object"},"404":{"description":"Event not found"}},"security":[{"bearer":[]}],"summary":"Get event by ID","tags":["API v1 — Events"]},"patch":{"operationId":"V1EventsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":15,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateEventDto"}}}},"responses":{"200":{"description":"Updated event"},"404":{"description":"Event not found"}},"security":[{"bearer":[]}],"summary":"Update an event","tags":["API v1 — Events"]},"delete":{"description":"Deletes a single event. For recurring series, only this occurrence is removed.","operationId":"V1EventsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":15,"type":"number"}}],"responses":{"200":{"description":"Event deleted"},"404":{"description":"Event not found"}},"security":[{"bearer":[]}],"summary":"Delete an event","tags":["API v1 — Events"]}},"/api/v1/habits":{"get":{"description":"Returns all habits (active, planned, completed) sorted by status and creation date.","operationId":"V1HabitsController_list","parameters":[],"responses":{"200":{"description":"Array of habits"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `habits:read`"}},"security":[{"bearer":[]}],"summary":"List all habits","tags":["API v1 — Habits"]},"post":{"description":"Creates a new habit. Set `planned: true` to create in planned status (not yet active). `frequency_days` is an array of weekdays (0=Mon..6=Sun); null means every day.","operationId":"V1HabitsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateHabitDto"}}}},"responses":{"201":{"description":"Created habit"}},"security":[{"bearer":[]}],"summary":"Create a habit","tags":["API v1 — Habits"]}},"/api/v1/habits/summary":{"get":{"description":"Returns daily stats: how many habits were completed vs total scheduled, for each day in the range.","operationId":"V1HabitsController_summary","parameters":[{"name":"from","required":true,"in":"query","description":"From date YYYY-MM-DD","schema":{"type":"string"}},{"name":"to","required":true,"in":"query","description":"To date YYYY-MM-DD","schema":{"type":"string"}}],"responses":{"200":{"description":"Array of { date, completed, total }"}},"security":[{"bearer":[]}],"summary":"Daily completion summary","tags":["API v1 — Habits"]}},"/api/v1/habits/{id}":{"get":{"operationId":"V1HabitsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}}],"responses":{"200":{"description":"Habit object with streak info"},"404":{"description":"Habit not found"}},"security":[{"bearer":[]}],"summary":"Get habit by ID","tags":["API v1 — Habits"]},"patch":{"operationId":"V1HabitsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateHabitDto"}}}},"responses":{"200":{"description":"Updated habit"},"404":{"description":"Habit not found"}},"security":[{"bearer":[]}],"summary":"Update a habit","tags":["API v1 — Habits"]},"delete":{"operationId":"V1HabitsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}}],"responses":{"200":{"description":"Habit deleted"},"404":{"description":"Habit not found"}},"security":[{"bearer":[]}],"summary":"Delete a habit and all its logs","tags":["API v1 — Habits"]}},"/api/v1/habits/{id}/logs":{"get":{"description":"Returns daily check-in logs for a specific habit. Defaults to the full range since habit start.","operationId":"V1HabitsController_logs","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}},{"name":"from","required":false,"in":"query","description":"From date YYYY-MM-DD","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"To date YYYY-MM-DD","schema":{"type":"string"}}],"responses":{"200":{"description":"Array of log entries (date + count)"},"404":{"description":"Habit not found"}},"security":[{"bearer":[]}],"summary":"Get check-in logs","tags":["API v1 — Habits"]}},"/api/v1/habits/{id}/checkin":{"post":{"description":"Records one completion for today. Call multiple times for habits with `frequency_count > 1`.","operationId":"V1HabitsController_checkin","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}}],"responses":{"200":{"description":"Updated habit and today's log entry"},"404":{"description":"Habit not found"}},"security":[{"bearer":[]}],"summary":"Check in","tags":["API v1 — Habits"]}},"/api/v1/habits/{id}/undo-checkin":{"post":{"description":"Removes one completion from today. If count reaches 0, the log entry is deleted.","operationId":"V1HabitsController_undoCheckin","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}}],"responses":{"200":{"description":"Updated habit and log (or null if removed)"}},"security":[{"bearer":[]}],"summary":"Undo check-in","tags":["API v1 — Habits"]}},"/api/v1/habits/{id}/activate":{"post":{"description":"Moves a habit from `planned` to `active` status and resets the start date to today.","operationId":"V1HabitsController_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}}],"responses":{"200":{"description":"Activated habit"},"404":{"description":"Habit not found or not in planned status"}},"security":[{"bearer":[]}],"summary":"Activate a planned habit","tags":["API v1 — Habits"]}},"/api/v1/habits/{id}/postpone":{"post":{"description":"Moves an active habit back to `planned` status. Resets current streak but keeps total stats.","operationId":"V1HabitsController_postpone","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}}],"responses":{"200":{"description":"Postponed habit"},"404":{"description":"Habit not found or not active"}},"security":[{"bearer":[]}],"summary":"Postpone a habit","tags":["API v1 — Habits"]}},"/api/v1/habits/{id}/restart":{"post":{"description":"Fully resets the habit: clears all logs, resets streak and total to 0, sets status to active with today as start.","operationId":"V1HabitsController_restart","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":3,"type":"number"}}],"responses":{"200":{"description":"Restarted habit"},"404":{"description":"Habit not found"}},"security":[{"bearer":[]}],"summary":"Restart a habit","tags":["API v1 — Habits"]}},"/api/v1/nutrition/food-items":{"get":{"description":"Returns food items (global approved + user custom). Filter by name search and/or category.","operationId":"V1NutritionController_foodItems","parameters":[{"name":"search","required":false,"in":"query","description":"Search by name","schema":{"type":"string"}},{"name":"category","required":false,"in":"query","description":"Filter by category","schema":{"type":"string"}}],"responses":{"200":{"description":"Array of food items with nutritional data per serving"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `nutrition:read`"}},"security":[{"bearer":[]}],"summary":"Search food items","tags":["API v1 — Nutrition"]},"post":{"description":"Creates a personal food item. Nutritional values are per serving (default serving = 100g).","operationId":"V1NutritionController_createFoodItem","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateFoodItemDto"}}}},"responses":{"201":{"description":"Created food item"}},"security":[{"bearer":[]}],"summary":"Create a custom food item","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/food-items/categories":{"get":{"description":"Returns distinct category names across all food items.","operationId":"V1NutritionController_foodCategories","parameters":[],"responses":{"200":{"description":"Array of category strings"}},"security":[{"bearer":[]}],"summary":"List food categories","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/food-items/{id}":{"delete":{"operationId":"V1NutritionController_removeFoodItem","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":100,"type":"number"}}],"responses":{"200":{"description":"Food item deleted"},"403":{"description":"Cannot delete global food items"},"404":{"description":"Food item not found"}},"security":[{"bearer":[]}],"summary":"Delete a custom food item","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/meal-types":{"get":{"description":"Returns meal types (e.g. Breakfast, Lunch, Dinner, Snack). Auto-creates defaults on first access.","operationId":"V1NutritionController_mealTypes","parameters":[],"responses":{"200":{"description":"Array of meal types with id, name, sort_order"}},"security":[{"bearer":[]}],"summary":"List meal types","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/day-log":{"get":{"description":"Returns food logs grouped by meal type for the specified date. Each log includes calculated calories, protein, fat, carbs.","operationId":"V1NutritionController_dayLog","parameters":[{"name":"date","required":true,"in":"query","description":"Date YYYY-MM-DD","schema":{"example":"2026-05-14","type":"string"}}],"responses":{"200":{"description":"Array of { mealType, logs[] }"}},"security":[{"bearer":[]}],"summary":"Get food diary for a day","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/food-logs":{"post":{"description":"Records eating a food item or recipe. Provide either `food_item_id` or `recipe_id`. Calories/macros are calculated automatically from portions.","operationId":"V1NutritionController_addFoodLog","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateFoodLogDto"}}}},"responses":{"201":{"description":"Created food log with calculated macros"},"404":{"description":"Food item or recipe not found"}},"security":[{"bearer":[]}],"summary":"Log food consumption","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/food-logs/{id}":{"delete":{"operationId":"V1NutritionController_removeFoodLog","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":50,"type":"number"}}],"responses":{"200":{"description":"Log entry deleted"},"404":{"description":"Log entry not found"}},"security":[{"bearer":[]}],"summary":"Delete a food log entry","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/water":{"get":{"description":"Returns water log entries and total_ml for the specified date.","operationId":"V1NutritionController_waterLogs","parameters":[{"name":"date","required":true,"in":"query","description":"Date YYYY-MM-DD","schema":{"example":"2026-05-14","type":"string"}}],"responses":{"200":{"description":"{ logs: WaterLog[], total_ml: number }"}},"security":[{"bearer":[]}],"summary":"Get water intake for a day","tags":["API v1 — Nutrition"]},"post":{"operationId":"V1NutritionController_addWaterLog","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateWaterLogDto"}}}},"responses":{"201":{"description":"Created water log"}},"security":[{"bearer":[]}],"summary":"Log water intake","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/water/{id}":{"delete":{"operationId":"V1NutritionController_removeWaterLog","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":20,"type":"number"}}],"responses":{"200":{"description":"Water log deleted"},"404":{"description":"Water log not found"}},"security":[{"bearer":[]}],"summary":"Delete a water log entry","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/goals":{"get":{"description":"Returns daily targets for calories, protein, fat, carbs, and water. Auto-creates defaults on first access.","operationId":"V1NutritionController_goals","parameters":[],"responses":{"200":{"description":"Nutrition goals object"}},"security":[{"bearer":[]}],"summary":"Get nutrition goals","tags":["API v1 — Nutrition"]},"patch":{"operationId":"V1NutritionController_updateGoals","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateGoalsDto"}}}},"responses":{"200":{"description":"Updated goals"}},"security":[{"bearer":[]}],"summary":"Update nutrition goals","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/recipes":{"get":{"description":"Returns user recipes and approved public recipes. Each includes ingredients and calculated macros per serving.","operationId":"V1NutritionController_recipes","parameters":[{"name":"search","required":false,"in":"query","description":"Search by name","schema":{"type":"string"}}],"responses":{"200":{"description":"Array of recipes with ingredients"}},"security":[{"bearer":[]}],"summary":"List recipes","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/recipes/{id}":{"get":{"operationId":"V1NutritionController_recipe","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":5,"type":"number"}}],"responses":{"200":{"description":"Recipe with ingredients and macros"},"404":{"description":"Recipe not found"}},"security":[{"bearer":[]}],"summary":"Get recipe by ID","tags":["API v1 — Nutrition"]}},"/api/v1/nutrition/fridge":{"get":{"description":"Returns items currently in the fridge with portion counts. Portions are auto-decremented when food is logged.","operationId":"V1NutritionController_fridge","parameters":[],"responses":{"200":{"description":"Array of fridge items"}},"security":[{"bearer":[]}],"summary":"List fridge items","tags":["API v1 — Nutrition"]}},"/api/v1/finance/accounts":{"get":{"description":"Returns all accounts with current calculated balances. Balance is in currency units (e.g. rubles, not kopecks).","operationId":"V1FinanceController_listAccounts","parameters":[],"responses":{"200":{"description":"Array of accounts with current_balance field"},"401":{"description":"Invalid or missing PAT token"},"403":{"description":"Token missing required scope `finance:read`"}},"security":[{"bearer":[]}],"summary":"List finance accounts","tags":["API v1 — Finance"]}},"/api/v1/finance/accounts/{id}":{"get":{"operationId":"V1FinanceController_getAccount","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Account with current_balance"},"404":{"description":"Account not found"}},"security":[{"bearer":[]}],"summary":"Get account by ID with current balance","tags":["API v1 — Finance"]}},"/api/v1/finance/categories":{"get":{"description":"Returns all categories used to classify transactions (e.g. Food, Transport, Salary).","operationId":"V1FinanceController_listCategories","parameters":[],"responses":{"200":{"description":"Array of categories"}},"security":[{"bearer":[]}],"summary":"List finance categories","tags":["API v1 — Finance"]}},"/api/v1/finance/transactions":{"get":{"description":"Returns transactions with optional filters and pagination. Amount is in currency units (rubles). Sorted by date descending.","operationId":"V1FinanceController_listTransactions","parameters":[{"name":"account_id","required":false,"in":"query","schema":{"type":"number"}},{"name":"category_id","required":false,"in":"query","schema":{"type":"number"}},{"name":"type","required":false,"in":"query","schema":{"type":"string","enum":["income","expense"]}},{"name":"date_from","required":false,"in":"query","description":"From date YYYY-MM-DD","schema":{"type":"string"}},{"name":"date_to","required":false,"in":"query","description":"To date YYYY-MM-DD","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","schema":{"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"default":50,"type":"number"}}],"responses":{"200":{"description":"{ items: Transaction[], total: number, page: number, limit: number }"}},"security":[{"bearer":[]}],"summary":"List transactions","tags":["API v1 — Finance"]},"post":{"description":"Creates an income or expense transaction. `amount` is in currency units (e.g. 1500.50 for 1500 rubles 50 kopecks). Multi-currency is supported — amount_rub is calculated automatically.","operationId":"V1FinanceController_createTransaction","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateTransactionDto"}}}},"responses":{"201":{"description":"Created transaction with amount in currency units"},"404":{"description":"Account not found"}},"security":[{"bearer":[]}],"summary":"Create a transaction","tags":["API v1 — Finance"]}},"/api/v1/finance/transactions/{id}":{"get":{"operationId":"V1FinanceController_getTransaction","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":100,"type":"number"}}],"responses":{"200":{"description":"Transaction object"},"404":{"description":"Transaction not found"}},"security":[{"bearer":[]}],"summary":"Get transaction by ID","tags":["API v1 — Finance"]},"patch":{"operationId":"V1FinanceController_updateTransaction","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":100,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateTransactionDto"}}}},"responses":{"200":{"description":"Updated transaction"},"404":{"description":"Transaction not found"}},"security":[{"bearer":[]}],"summary":"Update a transaction","tags":["API v1 — Finance"]},"delete":{"operationId":"V1FinanceController_removeTransaction","parameters":[{"name":"id","required":true,"in":"path","schema":{"example":100,"type":"number"}}],"responses":{"200":{"description":"Transaction deleted"},"404":{"description":"Transaction not found"}},"security":[{"bearer":[]}],"summary":"Delete a transaction","tags":["API v1 — Finance"]}},"/api/v1/planner/preparation-stats":{"get":{"description":"Returns projects without ICE scores, tasks without estimates/complexity, and tasks without projects. Use to check readiness before generating a plan.","operationId":"V1PlannerController_getPreparationStats","parameters":[{"name":"stream_ids","required":false,"in":"query","description":"Comma-separated stream IDs to filter","schema":{"type":"string"}}],"responses":{"200":{"description":"Preparation stats"}},"security":[{"bearer":[]}],"summary":"Get preparation stats for planning","tags":["API v1 — Planner"]}},"/api/v1/planner/settings":{"get":{"description":"Returns planner settings for the current user (working hours, schedule, energy levels).","operationId":"V1PlannerController_getSettings","parameters":[],"responses":{"200":{"description":"Planner settings object"}},"security":[{"bearer":[]}],"summary":"Get planner settings","tags":["API v1 — Planner"]},"patch":{"operationId":"V1PlannerController_updateSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSettingsDto"}}}},"responses":{"200":{"description":"Updated settings"}},"security":[{"bearer":[]}],"summary":"Update planner settings","tags":["API v1 — Planner"]}},"/api/v1/planner/generate":{"post":{"description":"Creates a draft plan by scheduling eligible tasks into available time slots. Tasks must have estimated_hours, complexity, and belong to a project with ICE scores.","operationId":"V1PlannerController_generate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeneratePlanDto"}}}},"responses":{"201":{"description":"Generated plan: session, items, overflow, stats"}},"security":[{"bearer":[]}],"summary":"Generate a plan","tags":["API v1 — Planner"]}},"/api/v1/planner/sessions/{id}":{"get":{"operationId":"V1PlannerController_getSession","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"Session with plan items"},"404":{"description":"Session not found"}},"security":[{"bearer":[]}],"summary":"Get plan session with items","tags":["API v1 — Planner"]},"delete":{"operationId":"V1PlannerController_deleteSession","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":"Deleted"}},"security":[{"bearer":[]}],"summary":"Delete a plan session","tags":["API v1 — Planner"]}},"/api/v1/planner/sessions/{id}/apply":{"post":{"description":"Creates calendar events for all planned items.","operationId":"V1PlannerController_applySession","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"Applied session"},"404":{"description":"Draft session not found"}},"security":[{"bearer":[]}],"summary":"Apply plan to calendar","tags":["API v1 — Planner"]}},"/api/v1/bitrix24":{"get":{"description":"Returns all B24 integrations for the user","operationId":"V1Bitrix24Controller_list","parameters":[],"responses":{"200":{"description":"Array of integrations"}},"security":[{"bearer":[]}],"summary":"List Bitrix24 integrations","tags":["API v1 — Bitrix24"]}},"/api/v1/bitrix24/{id}/status":{"get":{"description":"Returns sync status for a specific B24 integration","operationId":"V1Bitrix24Controller_status","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"Integration details with sync status"}},"security":[{"bearer":[]}],"summary":"Get sync status","tags":["API v1 — Bitrix24"]}},"/api/v1/bitrix24/{id}/sync":{"post":{"description":"Manually trigger B24 sync (pull + push)","operationId":"V1Bitrix24Controller_sync","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"Sync result with pull/push stats"}},"security":[{"bearer":[]}],"summary":"Trigger sync","tags":["API v1 — Bitrix24"]}},"/api/v1/bitrix24/issues/{issueId}/resolve-conflict":{"post":{"description":"Mark a task conflict as resolved (accept current values)","operationId":"V1Bitrix24Controller_resolveConflict","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Resolve sync conflict","tags":["API v1 — Bitrix24"]}},"/api/v1/kb/tree":{"get":{"operationId":"V1KnowledgeBaseController_tree","parameters":[{"name":"stream","required":false,"in":"query","description":"Filter tree by stream name/key/ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"parent_id","required":false,"in":"query","description":"Subtree starting from folder ID","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get knowledge base tree (folders + articles)","tags":["API v1 — Knowledge Base"]}},"/api/v1/kb/folders":{"get":{"operationId":"V1KnowledgeBaseController_listFolders","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List all KB folders (flat)","tags":["API v1 — Knowledge Base"]},"post":{"operationId":"V1KnowledgeBaseController_createFolder","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateFolderDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Create a KB folder","tags":["API v1 — Knowledge Base"]}},"/api/v1/kb/folders/{id}":{"get":{"operationId":"V1KnowledgeBaseController_getFolder","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get folder by ID","tags":["API v1 — Knowledge Base"]},"patch":{"operationId":"V1KnowledgeBaseController_updateFolder","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateFolderDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Update a KB folder","tags":["API v1 — Knowledge Base"]},"delete":{"operationId":"V1KnowledgeBaseController_removeFolder","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete a KB folder (cascade)","tags":["API v1 — Knowledge Base"]}},"/api/v1/kb/articles":{"get":{"operationId":"V1KnowledgeBaseController_listArticles","parameters":[{"name":"folder_id","required":false,"in":"query","description":"Filter by folder ID","schema":{"type":"number"}},{"name":"stream","required":false,"in":"query","description":"Filter by stream name/key/ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"tag","required":false,"in":"query","description":"Filter by tag name","schema":{"type":"string"}},{"name":"search","required":false,"in":"query","description":"Full-text search","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"default":50,"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List KB articles with filters","tags":["API v1 — Knowledge Base"]},"post":{"operationId":"V1KnowledgeBaseController_createArticle","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateArticleDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Create a KB article","tags":["API v1 — Knowledge Base"]}},"/api/v1/kb/articles/{id}":{"get":{"operationId":"V1KnowledgeBaseController_getArticle","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get KB article by ID (with content and tags)","tags":["API v1 — Knowledge Base"]},"patch":{"operationId":"V1KnowledgeBaseController_updateArticle","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateArticleDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Update a KB article","tags":["API v1 — Knowledge Base"]},"delete":{"operationId":"V1KnowledgeBaseController_removeArticle","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete a KB article","tags":["API v1 — Knowledge Base"]}},"/api/v1/kb/search":{"get":{"operationId":"V1KnowledgeBaseController_searchArticles","parameters":[{"name":"q","required":true,"in":"query","schema":{"type":"string"}},{"name":"folder_id","required":false,"in":"query","description":"Filter by folder ID","schema":{"type":"number"}},{"name":"stream","required":false,"in":"query","description":"Filter by stream name/key/ID","schema":{"$ref":"#/components/schemas/Object"}},{"name":"tag","required":false,"in":"query","description":"Filter by tag name","schema":{"type":"string"}},{"name":"search","required":false,"in":"query","description":"Full-text search","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"default":50,"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Full-text search KB articles (OpenSearch with MySQL fallback)","tags":["API v1 — Knowledge Base"]}},"/api/v1/kb/reindex":{"post":{"operationId":"V1KnowledgeBaseController_reindex","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Reindex all KB articles into OpenSearch","tags":["API v1 — Knowledge Base"]}},"/api/v1/kb/tags":{"get":{"operationId":"V1KnowledgeBaseController_listTags","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List all KB tags","tags":["API v1 — Knowledge Base"]}}},"info":{"title":"Mnogodel API v1","description":"## Authentication\n\nAll endpoints require a **Personal Access Token (PAT)**.\n\n1. Go to **Settings → API Keys** in your Mnogodel cabinet\n2. Create a token with the required scopes\n3. Pass it in the `Authorization` header: `Bearer mnd_...`\n\nToken prefix: `mnd_`. Each token has scoped permissions — a request to an endpoint without the required scope returns `403`.\n\n## Rate Limits\n\n`1000` requests per minute per token. Check `X-RateLimit-Remaining` header.\n\n## Resolving by name\n\nStreams, projects, and tags can be referenced by **name** or **numeric ID** — e.g. `\"stream\": \"Development\"` or `\"stream\": 1`.","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Personal Access Token (mnd_...)"}},"schemas":{"V1ActivityDto":{"type":"object","properties":{"title":{"type":"string","example":"Code review","description":"Activity title"},"tags":{"example":["Development",1],"description":"Tag names or IDs to attach to this activity","type":"array","items":{"type":"string"}},"started_at":{"type":"string","example":"2026-05-14T10:00:00.000Z","description":"Activity start time (ISO 8601)"},"ended_at":{"type":"string","example":"2026-05-14T11:30:00.000Z","description":"Activity end time (ISO 8601)"}}},"V1TrackerStartDto":{"type":"object","properties":{"description":{"type":"string","example":"Working on API docs","description":"Entry description"},"activities":{"description":"Activities to add immediately (replaces auto-created empty activity)","type":"array","items":{"$ref":"#/components/schemas/V1ActivityDto"}}}},"V1TrackerStopDto":{"type":"object","properties":{"description":{"type":"string","example":"Finished the feature","description":"Final description for the stopped entry"},"activities":{"description":"Activities for the new entry (only used if restart=true)","type":"array","items":{"$ref":"#/components/schemas/V1ActivityDto"}},"restart":{"type":"boolean","default":false,"description":"If true, immediately start a new entry after stopping"}}},"V1TrackerLogDto":{"type":"object","properties":{"started_at":{"type":"string","example":"2026-05-14T09:00:00.000Z","description":"Entry start time (ISO 8601)"},"ended_at":{"type":"string","example":"2026-05-14T12:00:00.000Z","description":"Entry end time (ISO 8601)"},"description":{"type":"string","example":"Retroactive entry","description":"Entry description"},"activities":{"description":"Activities for this entry","type":"array","items":{"$ref":"#/components/schemas/V1ActivityDto"}}},"required":["started_at","ended_at"]},"Object":{"type":"object","properties":{}},"V1CreateTaskDto":{"type":"object","properties":{"title":{"type":"string","example":"Implement login page","description":"Task title"},"description":{"type":"string","example":"Add OAuth2 support with Google provider","description":"Task description (markdown)"},"stream":{"example":"Development","description":"Stream name, key, or numeric ID","oneOf":[{"type":"string"},{"type":"number"}]},"project":{"example":"Website","description":"Project name or numeric ID","oneOf":[{"type":"string"},{"type":"number"}]},"status":{"type":"string","example":"open","enum":["open","in_progress","done","cancelled"],"default":"open"},"priority":{"type":"string","example":"medium","enum":["low","medium","high","urgent"],"default":"medium"},"due_date":{"type":"string","example":"2026-06-01","description":"Due date / deadline (YYYY-MM-DD)"},"start_date_plan":{"type":"string","example":"2026-05-25","description":"Planned start date (YYYY-MM-DD). For Gantt chart / B24 START_DATE_PLAN."},"end_date_plan":{"type":"string","example":"2026-06-01","description":"Planned end date (YYYY-MM-DD). For Gantt chart / B24 END_DATE_PLAN."},"tags":{"type":"string","example":"frontend,auth","description":"Comma-separated tags"},"estimated_hours":{"type":"number","example":4,"description":"Estimated hours"},"complexity":{"type":"string","example":"medium","enum":["trivial","easy","medium","hard"],"description":"Task complexity for energy-based scheduling"}},"required":["title","stream"]},"V1UpdateTaskDto":{"type":"object","properties":{"title":{"type":"string","example":"Updated title"},"description":{"type":"string","example":"Updated description"},"status":{"type":"string","example":"in_progress","enum":["open","in_progress","done","cancelled"]},"priority":{"type":"string","example":"high","enum":["low","medium","high","urgent"]},"due_date":{"type":"string","example":"2026-06-15","description":"Due date / deadline (YYYY-MM-DD)"},"start_date_plan":{"type":"string","example":"2026-06-10","description":"Planned start date (YYYY-MM-DD)"},"end_date_plan":{"type":"string","example":"2026-06-15","description":"Planned end date (YYYY-MM-DD)"},"tags":{"type":"string","example":"frontend,refactor"},"estimated_hours":{"type":"number","example":8},"actual_hours":{"type":"number","example":6,"description":"Actual hours spent"},"complexity":{"type":"string","example":"hard","enum":["trivial","easy","medium","hard"],"description":"Task complexity for energy-based scheduling"}}},"V1CreateProjectDto":{"type":"object","properties":{"name":{"type":"string","example":"Website redesign","description":"Project name"},"stream":{"example":"Development","description":"Stream name, key, or numeric ID","oneOf":[{"type":"string"},{"type":"number"}]},"description":{"type":"string","example":"Full redesign of the public website","description":"Project description"},"priority":{"type":"string","example":"medium","enum":["low","medium","high","urgent"]},"color":{"type":"string","example":"#3B82F6","description":"Color hex code"},"ice_impact":{"type":"number","example":8,"description":"ICE scoring: Impact (1-10)","minimum":1,"maximum":10},"ice_confidence":{"type":"number","example":7,"description":"ICE scoring: Confidence (1-10)","minimum":1,"maximum":10},"ice_ease":{"type":"number","example":6,"description":"ICE scoring: Ease (1-10)","minimum":1,"maximum":10}},"required":["name","stream"]},"V1UpdateProjectDto":{"type":"object","properties":{"name":{"type":"string","example":"Updated name"},"description":{"type":"string","example":"Updated description"},"status":{"type":"string","example":"active","enum":["active","paused","completed","cancelled"]},"priority":{"type":"string","example":"high","enum":["low","medium","high","urgent"]},"color":{"type":"string","example":"#EF4444"},"ice_impact":{"type":"number","example":8,"description":"ICE: Impact (1-10)","minimum":1,"maximum":10},"ice_confidence":{"type":"number","example":7,"description":"ICE: Confidence (1-10)","minimum":1,"maximum":10},"ice_ease":{"type":"number","example":6,"description":"ICE: Ease (1-10)","minimum":1,"maximum":10}}},"V1CreateStreamDto":{"type":"object","properties":{"name":{"type":"string","example":"Development","description":"Stream name"},"key":{"type":"string","example":"DEV","description":"Short key (used in task IDs like DEV-42)"},"description":{"type":"string","example":"Software development work","description":"Stream description"},"color":{"type":"string","example":"#8B5CF6","description":"Color hex code"}},"required":["name","key"]},"V1UpdateStreamDto":{"type":"object","properties":{"name":{"type":"string","example":"Updated name"},"description":{"type":"string","example":"Updated description"},"color":{"type":"string","example":"#EF4444"},"is_active":{"type":"boolean","example":false,"description":"Set to false to archive the stream"}}},"V1CreateNoteDto":{"type":"object","properties":{"title":{"type":"string","example":"Meeting notes","description":"Note title"},"content":{"type":"string","example":"# Summary\nDiscussed the roadmap...","description":"Note content (markdown)"},"stream":{"example":"Development","description":"Stream name, key, or numeric ID","oneOf":[{"type":"string"},{"type":"number"}]},"project":{"example":"Website","description":"Project name or numeric ID","oneOf":[{"type":"string"},{"type":"number"}]},"issue_id":{"type":"number","example":42,"description":"Link to a task by ID"}}},"V1UpdateNoteDto":{"type":"object","properties":{"title":{"type":"string","example":"Updated title"},"content":{"type":"string","example":"Updated content"}}},"V1CreateEventDto":{"type":"object","properties":{"title":{"type":"string","example":"Team meeting"},"description":{"type":"string"},"start_date":{"type":"string","example":"2026-05-15T10:00:00.000Z"},"end_date":{"type":"string","example":"2026-05-15T11:00:00.000Z"},"all_day":{"type":"boolean","default":false},"calendar_id":{"type":"number","description":"Calendar ID (uses default if not provided)"},"location":{"type":"string"},"color":{"type":"string","example":"#3B82F6"},"type":{"type":"string","enum":["event","task","reminder"]}},"required":["title","start_date","end_date"]},"V1UpdateEventDto":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"start_date":{"type":"string"},"end_date":{"type":"string"},"all_day":{"type":"boolean"},"calendar_id":{"type":"number"},"location":{"type":"string"},"color":{"type":"string"},"type":{"type":"string"}}},"V1CreateHabitDto":{"type":"object","properties":{"name":{"type":"string","example":"Morning meditation"},"description":{"type":"string"},"frequency_count":{"type":"number","default":1,"description":"How many times per day"},"frequency_days":{"description":"Days of week (0=Mon..6=Sun), null = every day","type":"array","items":{"type":"number"}},"target_days":{"type":"number","default":21,"description":"Target streak days"},"color":{"type":"string","example":"#10B981"},"reminder_time":{"type":"string","example":"09:00","description":"Reminder time HH:MM"},"planned":{"type":"boolean","default":false,"description":"Create as planned (not active)"}},"required":["name"]},"V1UpdateHabitDto":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"frequency_count":{"type":"number"},"frequency_days":{"type":"array","items":{"type":"number"}},"target_days":{"type":"number"},"color":{"type":"string"},"reminder_time":{"type":"string"}}},"V1CreateFoodItemDto":{"type":"object","properties":{"name":{"type":"string","example":"Chicken breast"},"brand":{"type":"string"},"calories_per_serving":{"type":"number","default":0},"protein_per_serving":{"type":"number","default":0},"fat_per_serving":{"type":"number","default":0},"carbs_per_serving":{"type":"number","default":0},"serving_size":{"type":"number","default":100},"serving_unit":{"type":"string","default":"g"},"category":{"type":"string"}},"required":["name"]},"V1CreateFoodLogDto":{"type":"object","properties":{"meal_type_id":{"type":"number","description":"Meal type ID"},"food_item_id":{"type":"number","description":"Food item ID (either this or recipe_id)"},"recipe_id":{"type":"number","description":"Recipe ID (either this or food_item_id)"},"date":{"type":"string","example":"2026-05-14"},"portions":{"type":"number","default":1}},"required":["meal_type_id","date","portions"]},"V1CreateWaterLogDto":{"type":"object","properties":{"amount_ml":{"type":"number","example":250},"date":{"type":"string","example":"2026-05-14"}},"required":["amount_ml","date"]},"V1UpdateGoalsDto":{"type":"object","properties":{"calories_target":{"type":"number"},"protein_target":{"type":"number"},"fat_target":{"type":"number"},"carbs_target":{"type":"number"},"water_target_ml":{"type":"number"}}},"V1CreateTransactionDto":{"type":"object","properties":{"account_id":{"type":"number"},"amount":{"type":"number","description":"Amount in currency units (e.g. rubles, not kopecks)"},"type":{"type":"string","enum":["income","expense"]},"date":{"type":"string","example":"2026-05-14"},"description":{"type":"string"},"category_id":{"type":"number"},"currency":{"type":"string","default":"RUB"}},"required":["account_id","amount","type","date"]},"V1UpdateTransactionDto":{"type":"object","properties":{"amount":{"type":"number"},"type":{"type":"string","enum":["income","expense"]},"date":{"type":"string"},"description":{"type":"string"},"category_id":{"type":"number"},"currency":{"type":"string"}}},"UpdateSettingsDto":{"type":"object","properties":{"working_hours_start":{"type":"string","example":"09:00","description":"Working hours start (HH:mm)"},"working_hours_end":{"type":"string","example":"18:00","description":"Working hours end (HH:mm)"},"work_schedule_type":{"type":"string","example":"weekdays","enum":["weekdays","everyday","custom"]},"work_days":{"example":[1,2,3,4,5],"description":"Work days (1=Mon..7=Sun)","type":"array","items":{"type":"string"}},"break_minutes":{"type":"number","example":15,"description":"Break between blocks (minutes)"},"max_block_minutes":{"type":"number","example":120,"description":"Max block duration (minutes)"},"energy_levels":{"type":"object","description":"Energy levels configuration","example":{"high":{"start":"09:00","end":"12:00"},"medium":{"start":"13:00","end":"16:00"},"low":{"start":"16:00","end":"18:00"}}}}},"GeneratePlanDto":{"type":"object","properties":{"stream_ids":{"example":[1,3],"description":"Stream IDs to include in planning","type":"array","items":{"type":"string"}},"calendar_ids":{"example":[1,2],"description":"Calendar IDs to check for occupied time","type":"array","items":{"type":"string"}},"date_from":{"type":"string","example":"2026-05-19","description":"Plan start date (YYYY-MM-DD)"},"date_to":{"type":"string","example":"2026-05-23","description":"Plan end date (YYYY-MM-DD)"},"reset_existing":{"type":"boolean","example":false,"description":"Reset existing draft plans"}},"required":["stream_ids","calendar_ids","date_from","date_to"]},"V1CreateFolderDto":{"type":"object","properties":{"title":{"type":"string","example":"Programming","description":"Folder title"},"parent_id":{"type":"object","example":1,"description":"Parent folder ID (null = root)"},"icon":{"type":"object","example":"📚","description":"Emoji icon"},"stream":{"type":"object","description":"Stream name, key, or numeric ID"},"sort_order":{"type":"number"}},"required":["title"]},"V1UpdateFolderDto":{"type":"object","properties":{"title":{"type":"string"},"parent_id":{"type":"object"},"icon":{"type":"object"},"stream":{"type":"object"},"sort_order":{"type":"number"}}},"V1CreateArticleDto":{"type":"object","properties":{"title":{"type":"string","example":"How to use TypeORM migrations","description":"Article title"},"content":{"type":"object","description":"Markdown content"},"folder_id":{"type":"object","description":"Folder ID (null = root)"},"stream":{"type":"object","description":"Stream name, key, or numeric ID"},"is_pinned":{"type":"boolean"},"tags":{"description":"Tag names (created if not exist)","type":"array","items":{"type":"string"}}},"required":["title"]},"V1UpdateArticleDto":{"type":"object","properties":{"title":{"type":"string"},"content":{"type":"object"},"folder_id":{"type":"object"},"stream":{"type":"object"},"is_pinned":{"type":"boolean"},"tags":{"description":"Tag names (replaces all)","type":"array","items":{"type":"string"}}}}}}}