Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Contributing

Thank you for contributing to this project. The usual workflow is to choose or
create a GitHub issue, make a focused change, and open a pull request that links
to the issue.

## 1. Find or create an issue

Before starting work:

1. Check the repository's GitHub issues to see whether the change has already
been requested or is in progress.
2. Choose an existing issue, or create a new one that clearly describes the
problem, proposed change, and expected behavior.
3. Use the issue discussion to clarify requirements before making a large or
potentially breaking change.

## 2. Set up the project

Clone the repository:

```bash
git clone https://github.com/ibadia/fullstack-template.git
cd fullstack-template
```

Create a branch from the latest default branch:

```bash
git switch main
git pull origin main
git switch -c <issue-number>-short-description
```

Follow the setup instructions in [README.md](README.md) for the backend,
frontend, or both, depending on your change.

## 3. Make and verify the change

- Keep the change focused on the linked issue.
- Follow the existing code style and update documentation when behavior changes.
- Add or update tests for changed behavior.
- Do not commit secrets, local environment files, generated files, or unrelated
formatting changes.

Run the relevant checks before opening a pull request.

Backend:

```bash
cd backend
python -m pytest
ruff check .
black --check .
```

Frontend:

```bash
cd frontend
npm run lint
npm run build
```

## 4. Commit and push

Write a concise commit message that explains the change:

```bash
git add .
git commit -m "Add concise description of change"
git push -u origin <issue-number>-short-description
```

## 5. Open a pull request

Open a pull request from your branch to the repository's default branch. In the
pull request:

- Explain what changed and why.
- Link the issue with a closing keyword, such as `Fixes #123`, `Closes #123`,
or `Resolves #123`. GitHub will close the linked issue when the pull request
is merged.
- Describe how you tested the change.
- Include screenshots or recordings for visible user-interface changes.
- Keep the pull request limited to one issue whenever practical.

Respond to review feedback with additional commits. Avoid rewriting published
history unless a maintainer asks you to do so.
Binary file not shown.
3 changes: 3 additions & 0 deletions .vs/PythonSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"TestFramework": "Pytest"
}
17 changes: 17 additions & 0 deletions .vs/VSWorkspaceState.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"ExpandedNodes": [
"",
"\\backend",
"\\backend\\apps",
"\\backend\\apps\\receipts",
"\\backend\\apps\\receipts\\services",
"\\backend\\apps\\receipts\\utils",
"\\backend\\utils",
"\\backend\\utils\\logging",
"\\backend\\utils\\middleware",
"\\frontend",
"\\frontend\\app\\welcome"
],
"SelectedNode": "\\backend\\utils\\logging\\filters.py",
"PreviewInSolutionExplorer": false
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .vs/fullstack-ai/v17/.wsuo
Binary file not shown.
364 changes: 364 additions & 0 deletions .vs/fullstack-ai/v17/DocumentLayout.backup.json

Large diffs are not rendered by default.

41 changes: 41 additions & 0 deletions .vs/fullstack-ai/v17/DocumentLayout.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\ALI\\source\\repos\\asadriz\\fullstack-ai\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\ALI\\source\\repos\\asadriz\\fullstack-ai\\backend\\TESTING_SECURITY.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:backend\\TESTING_SECURITY.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 0,
"Children": [
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "TESTING_SECURITY.md",
"DocumentMoniker": "C:\\Users\\ALI\\source\\repos\\asadriz\\fullstack-ai\\backend\\TESTING_SECURITY.md",
"RelativeDocumentMoniker": "backend\\TESTING_SECURITY.md",
"ToolTip": "C:\\Users\\ALI\\source\\repos\\asadriz\\fullstack-ai\\backend\\TESTING_SECURITY.md",
"RelativeToolTip": "backend\\TESTING_SECURITY.md",
"ViewState": "AgIAAEoAAAAAAAAAAAAiwFgAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
"WhenOpened": "2026-07-31T07:02:39.077Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
}
]
}
]
}
]
}
Binary file added .vs/slnx.sqlite
Binary file not shown.
26 changes: 17 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@ frontend, or both, depending on your change.
- Do not commit secrets, local environment files, generated files, or unrelated
formatting changes.

### Architectural Decisions

#### Receipt Processing (MVP)
For MVP reliability, receipt analysis uses **synchronous processing by default**. This means:
- Analysis happens immediately during the request/response cycle
- Simple, reliable, no queue infrastructure required
- Better suited for reviewers testing without Celery setup
- Supports file uploads up to 10MB per request timeout

**Optional Async Mode**: When Celery is properly configured (with Redis/RabbitMQ and worker processes), you can enable background processing by setting `RECEIPT_PROCESSING_MODE=async` in `.env`. This trades immediate response for:
- Scalability to thousands of concurrent receipts
- Better resource utilization
- Non-blocking file uploads

See `backend/RECEIPT_ANALYSIS.md` for detailed configuration.

Run the relevant checks before opening a pull request.

Backend:
Expand Down Expand Up @@ -78,12 +94,4 @@ Open a pull request from your branch to the repository's default branch. In the
pull request:

- Explain what changed and why.
- Link the issue with a closing keyword, such as `Fixes #123`, `Closes #123`,
or `Resolves #123`. GitHub will close the linked issue when the pull request
is merged.
- Describe how you tested the change.
- Include screenshots or recordings for visible user-interface changes.
- Keep the pull request limited to one issue whenever practical.

Respond to review feedback with additional commits. Avoid rewriting published
history unless a maintainer asks you to do so.
- Link the issue with a closing keyword, such as "Closes #123".
94 changes: 87 additions & 7 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -1,20 +1,100 @@
# Copy this file to .env and fill in values for local development.
# Django
SECRET_KEY=change-me
# NEVER commit .env file - it contains secrets!

# ============================================================================
# DJANGO CORE
# ============================================================================

# Generate with: python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
SECRET_KEY=your-secret-key-minimum-50-chars

# Environment: development, staging, or production
# - development: Permissive CORS, Debug=True, verbose logging
# - staging: Like production, but allows testing
# - production: Strict security, HTTPS only, no debug info
ENVIRONMENT=development
DEBUG=True

# Database (django-environ DATABASE_URL). Use SQLite for local dev:
# ============================================================================
# DATABASE
# ============================================================================

# For local development, use SQLite:
DATABASE_URL=sqlite:///db.sqlite3
# Or PostgreSQL: postgres://admin:admin@localhost:5432/app_db

# URLs
# For production, use PostgreSQL:
# DATABASE_URL=postgres://user:password@localhost:5432/app_db

# ============================================================================
# SECURITY & CORS
# ============================================================================

# Production only: Set this to your frontend domain
# Example: https://example.com,https://www.example.com
# Development: Leave empty (or set to localhost:3000)
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000

# Production: List of allowed hosts (comma-separated)
# Development: Automatically includes localhost
ALLOWED_HOSTS=localhost,127.0.0.1,*.local

# ============================================================================
# FRONTEND & BACKEND URLS
# ============================================================================

FRONTEND_URL=http://localhost:3000
BACKEND_URL=http://localhost:8000

# Celery / Redis (only needed when running Celery workers)
# ============================================================================
# CELERY / REDIS (Optional - only if using async receipt processing)
# ============================================================================

# For async receipt processing, enable RECEIPT_PROCESSING_MODE=async
# and start a Celery worker: celery -A core worker -l info

CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/1

# Optional OnLogs service credentials (required only for `docker compose up -d onlogs`)
# ============================================================================
# RECEIPT ANALYSIS CONFIGURATION
# ============================================================================

# Processing mode: 'sync' (default, MVP) or 'async' (requires Celery)
# - sync: Analysis during request. Simple, reliable, no infrastructure.
# - async: Analysis in background. Scalable, requires Redis/RabbitMQ.
RECEIPT_PROCESSING_MODE=sync

# AI provider: 'mock' (default, no API key), 'openai', or 'anthropic'
# - mock: Free, realistic fake data, for development/testing
# - openai: GPT-4 Vision, requires OPENAI_API_KEY
# - anthropic: Claude 3, requires ANTHROPIC_API_KEY
RECEIPT_ANALYZER_PROVIDER=mock

# Optional: Timeout for receipt analysis (seconds)
RECEIPT_REQUEST_TIMEOUT=60

# ============================================================================
# AI PROVIDER CREDENTIALS
# ============================================================================

# NEVER commit these values! Store in .env (which is .gitignored)

# OpenAI API key (get from https://platform.openai.com/api-keys)
# Only required if RECEIPT_ANALYZER_PROVIDER=openai
OPENAI_API_KEY=sk-your-openai-api-key-here

# Anthropic API key (get from https://console.anthropic.com)
# Only required if RECEIPT_ANALYZER_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-your-anthropic-api-key-here

# Mock analyzer configuration (for testing failure scenarios)
# Set to value between 0 and 1 to simulate failures
# Example: 0.1 = 10% of requests will fail
MOCK_ANALYZER_FAILURE_RATE=0.0

# ============================================================================
# OPTIONAL: ONLOGS SERVICE (if using remote logging)
# ============================================================================

ONLOGS_ADMIN_USERNAME=admin
ONLOGS_ADMIN_PASSWORD=change-me
Loading