Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,31 @@ jobs:
- name: Run API tests
run: npm --prefix apps/api run test
env:
DATABASE_URL: postgresql://test:test@localhost:5432/fintrack_test
DATABASE_URL: postgresql://test:test@localhost:5432/fintrack_test

- name: Run Web tests
run: npm --prefix apps/web run test
env:
NEXT_PUBLIC_API_URL: http://localhost:8000/api
docker-build:
runs-on: ubuntu-latest
needs: check

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build Docker image (web)
uses: docker/build-push-action@v5
with:
context: .
file: apps/web/Dockerfile
push: false
build-args: |
NEXT_PUBLIC_API_URL=http://localhost:8000/api
tags: fintrack-web:ci
cache-from: type=gha
cache-to: type=gha,mode=max
85 changes: 85 additions & 0 deletions apps/api/src/docs/definitions/admin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
paths:
/admin/error-logs/report:
post:
tags: [Admin]
summary: Report client/runtime error from authenticated user
responses:
'201':
description: Error report created

/admin/users:
get:
tags: [Admin]
summary: List users (admin only)
responses:
'200':
description: Users list

/admin/users/{userId}/role:
patch:
tags: [Admin]
summary: Update user role (admin only)
parameters:
- in: path
name: userId
required: true
schema:
type: string
format: uuid
responses:
'200':
description: User role updated

/admin/sessions/revoke-user/{userId}:
post:
tags: [Admin]
summary: Revoke active sessions for specific user (admin only)
parameters:
- in: path
name: userId
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Revocation result

/admin/sessions/revoke-all:
post:
tags: [Admin]
summary: Revoke active sessions for all users (admin only)
responses:
'200':
description: Revocation result

/admin/stats:
get:
tags: [Admin]
summary: Get admin dashboard stats
responses:
'200':
description: Stats payload

/admin/error-logs:
get:
tags: [Admin]
summary: List error logs (admin only)
responses:
'200':
description: Error logs list

/admin/error-logs/{errorLogId}/resolve:
patch:
tags: [Admin]
summary: Mark error log resolved/unresolved (admin only)
parameters:
- in: path
name: errorLogId
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Updated error log status
127 changes: 62 additions & 65 deletions apps/api/src/docs/definitions/ai.yml
Original file line number Diff line number Diff line change
@@ -1,108 +1,105 @@
# ==================================
# COMPONENTS — AI
# ==================================
components:
schemas:
# --- Schemas for Request Bodies ---
AIRequestInput:
type: object
description: Input data for AI-powered transaction analysis or insight generation.
properties:
model:
type: string
description: Optional model identifier to use for inference. Defaults to `llama-3.1-8b-instant`.
example: "llama-3.1-8b-instant"
prompt:
type: string
description: Instruction or question for the AI model.
example: "Analyze the following transaction history and summarize spending habits."
data:
type: object
description: Additional structured data (such as transactions) to provide context for the AI model.
example:
transactions:
- title: "Groceries"
amount: 54.20
type: "EXPENSE"
- title: "Salary"
amount: 1200.00
type: "INCOME"
required:
- prompt
- data
required: [prompt, data]

# --- Schemas for Responses ---
AIResponse:
type: object
description: AI model response containing analytical text or generated insight.
properties:
model:
type: string
description: The model used to generate the response.
example: "llama-3.1-8b-instant"
result:
type: string
description: The AI-generated text result.
example: "You spent 40% of your income on food and transportation last month."

# --- Schemas for Errors ---
Error:
AIHistoryItem:
type: object
description: Standard error response.
properties:
error:
id:
type: string
description: Error message.
example:
error: "Something went wrong"
prompt:
type: string
result:
type: string
created_at:
type: string
format: date-time

AIAccess:
type: object
properties:
role:
type: string
enum: [USER, ADMIN]
tier:
type: string
enum: [user, donor, admin]
donationStatus:
type: string
donationExpiresAt:
type: [string, 'null']
format: date-time
aiAnalysisUsed:
type: integer
aiAnalysisLimit:
type: integer
remainingAttempts:
type: [integer, 'null']
isUnlimited:
type: boolean

# ==================================
# PATHS — AI
# ==================================
paths:
/ai:
post:
tags:
- AI
tags: [AI]
summary: Analyze financial data with AI
description:
Sends structured transaction data and an instruction prompt to the AI model for automated insights or recommendations.
This endpoint requires authentication and may return text-based analysis.
requestBody:
required: true
description: Input data and analysis request for the AI model.
content:
application/json:
schema:
$ref: "#/components/schemas/AIRequestInput"
$ref: '#/components/schemas/AIRequestInput'
responses:
"200":
description: Successful AI-generated response.
content:
application/json:
schema:
$ref: "#/components/schemas/AIResponse"
"400":
description: Invalid input data or prompt.
'200':
description: AI response
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
error: "Invalid input data or prompt"
"401":
description: Unauthorized (missing or invalid token).
$ref: '#/components/schemas/AIResponse'
'403':
description: AI limit reached
'503':
description: AI provider unavailable or key-related error

/ai/history:
get:
tags: [AI]
summary: Get AI prompts/results history for current user
responses:
'200':
description: History list
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
error: "Unauthorized"
"500":
description: AI service unavailable or all Groq API keys failed.
type: array
items:
$ref: '#/components/schemas/AIHistoryItem'

/ai/access:
get:
tags: [AI]
summary: Get current AI access tier and limits
responses:
'200':
description: Access status
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
error: "AI service unavailable"
$ref: '#/components/schemas/AIAccess'
Loading
Loading