{"id":34501396,"url":"https://github.com/afsanajamal/portfolio-platform-api","last_synced_at":"2026-04-13T15:33:40.853Z","repository":{"id":329917792,"uuid":"1120986010","full_name":"afsanajamal/portfolio-platform-api","owner":"afsanajamal","description":"FastAPI + PostgreSQL backend for a multi-tenant project \u0026 portfolio platform with JWT auth, RBAC, and tests","archived":false,"fork":false,"pushed_at":"2025-12-23T07:35:03.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-23T20:36:08.586Z","etag":null,"topics":["alembic","authentication","authorization","backend","ci-cd","docker","fastapi","github-actions","jwt","postgresql","pytest","python","rbac","rest-api","sqlalchemy"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/afsanajamal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-22T08:59:33.000Z","updated_at":"2025-12-23T09:14:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/afsanajamal/portfolio-platform-api","commit_stats":null,"previous_names":["afsanajamal/portfolio-platform-api"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/afsanajamal/portfolio-platform-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afsanajamal%2Fportfolio-platform-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afsanajamal%2Fportfolio-platform-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afsanajamal%2Fportfolio-platform-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afsanajamal%2Fportfolio-platform-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/afsanajamal","download_url":"https://codeload.github.com/afsanajamal/portfolio-platform-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afsanajamal%2Fportfolio-platform-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31759525,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T15:25:13.801Z","status":"ssl_error","status_checked_at":"2026-04-13T15:25:09.162Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alembic","authentication","authorization","backend","ci-cd","docker","fastapi","github-actions","jwt","postgresql","pytest","python","rbac","rest-api","sqlalchemy"],"created_at":"2025-12-24T02:01:35.642Z","updated_at":"2026-04-13T15:33:40.845Z","avatar_url":"https://github.com/afsanajamal.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Project \u0026 Portfolio Platform API\n\nA production-style backend API for managing projects and portfolios in a multi-tenant environment.\nBuilt with FastAPI and PostgreSQL, featuring JWT authentication, role-based access control (RBAC), audit logs, and automated tests.\n\nThis project is designed as a **portfolio-quality backend system**, suitable for academic evaluation and backend team review.\n\n---\n\n## Tech Stack\n\n- **Backend Framework**: FastAPI\n- **Language**: Python 3.13\n- **Database**: PostgreSQL (Dockerized for local development)\n- **ORM**: SQLAlchemy 2.0\n- **Migrations**: Alembic\n- **Authentication**: JWT (Access + Refresh tokens)\n- **Password Hashing**: Argon2\n- **Authorization**: Role-Based Access Control (RBAC)\n- **Testing**: Pytest + FastAPI TestClient\n- **API Documentation**: OpenAPI / Swagger\n- **CI/CD**: GitHub Actions\n\n---\n\n## Core Features\n\n### Authentication \u0026 Security\n- User registration and login\n- OAuth2 password flow\n- JWT-based authentication (access \u0026 refresh tokens)\n- Secure password hashing using Argon2\n- Token refresh mechanism for seamless user experience\n\n### Authorization (RBAC)\n- **Admin**\n  - Manage users and organizations\n  - Full CRUD access to all projects\n  - Access audit logs\n  - Delete any project\n- **Editor**\n  - Create and update projects\n  - Edit/delete own projects only\n  - Create tags\n- **Viewer**\n  - Read-only access to projects and tags\n  - No create/edit/delete permissions\n\n### Project Management\n- Create and manage projects within an organization\n- Tag-based project categorization\n- Public / private project visibility\n- Multi-tenant organization support\n- Project ownership and access control\n\n### Tag Management\n- Create and manage project tags\n- Tag-based filtering\n- Role-based tag creation (admin/editor only)\n\n### Audit Logging\n- Automatic activity logs for sensitive actions (e.g. project creation, user management)\n- Admin-only access to audit logs\n- Track who did what and when\n\n### Testing\n- 15+ comprehensive integration tests\n- Isolated test database (SQLite in-memory)\n- Auth, RBAC, and project CRUD tested\n- Edge case and error handling tests\n- GitHub Actions CI running on every push\n\n---\n\n## Documentation\n\nDetailed project documentation is available below:\n\n- [Project Overview](docs/overview.md) - Project goals, features, and scope\n- [Architecture \u0026 Structure](docs/architecture.md) - Technical architecture and patterns\n- [Architecture Decisions](docs/architecture-decisions.md) - Why we chose FastAPI, SQLAlchemy, Argon2, etc.\n- [API Endpoints](docs/api-endpoints.md) - Complete API reference with examples\n- [Authentication \u0026 RBAC](docs/auth-and-rbac.md) - Security implementation details\n- [Database Schema](docs/database-schema.md) - Database structure and relationships\n- [Testing \u0026 CI](docs/testing-and-ci.md) - Testing strategy and continuous integration\n- [Development Guide](docs/development.md) - Setup instructions and common tasks\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- Python 3.13+\n- Docker and Docker Compose (for PostgreSQL)\n- pip (Python package manager)\n\n### Installation\n\n1. **Clone the repository**\n   ```bash\n   git clone https://github.com/afsanajamal/portfolio-platform-api.git\n   cd portfolio-platform-api\n   ```\n\n2. **Create and activate virtual environment**\n   ```bash\n   python3 -m venv .venv\n   source .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\n   ```\n\n3. **Install dependencies**\n   ```bash\n   pip install -r requirements.txt\n   ```\n\n4. **Configure environment**\n   ```bash\n   cp .env.example .env\n   ```\n\n   Update `.env` with your configuration (defaults work for local development):\n   ```env\n   DATABASE_URL=postgresql+psycopg://portfolio:portfolio@localhost:5432/portfolio_db\n   JWT_SECRET=your-secret-key-change-this-in-production\n   JWT_ALGORITHM=HS256\n   ACCESS_TOKEN_EXPIRE_MINUTES=30\n   REFRESH_TOKEN_EXPIRE_DAYS=7\n   ```\n\n5. **Start PostgreSQL with Docker**\n   ```bash\n   docker-compose up -d\n   ```\n\n6. **Run database migrations**\n   ```bash\n   alembic upgrade head\n   ```\n\n7. **Seed test data**\n   ```bash\n   PYTHONPATH=. python scripts/seed_admin.py\n   ```\n\n8. **Start the development server**\n   ```bash\n   uvicorn app.main:app --reload\n   ```\n\n9. **Open API documentation**\n   ```\n   http://127.0.0.1:8000/docs\n   ```\n\n---\n\n## Available Scripts\n\n### Development\n- `uvicorn app.main:app --reload` – Start development server with auto-reload\n- `uvicorn app.main:app --host 0.0.0.0 --port 8000` – Start server on custom host/port\n\n### Testing\n- `pytest` – Run all tests\n- `pytest -v` – Run tests with verbose output\n- `pytest --cov=app` – Run tests with coverage report\n- `pytest tests/test_auth.py` – Run specific test file\n- `pytest -x` – Stop on first failure\n\n### Database\n- `alembic upgrade head` – Apply all migrations\n- `alembic downgrade -1` – Rollback one migration\n- `alembic revision --autogenerate -m \"message\"` – Create new migration\n- `alembic history` – Show migration history\n\n### Utilities\n- `PYTHONPATH=. python scripts/seed_admin.py` – Seed test users and organizations\n\n---\n\n## Test Accounts\n\nFor testing purposes, use these accounts (seeded via `scripts/seed_admin.py`):\n\n| Role   | Email                    | Password      |\n|--------|--------------------------|---------------|\n| Admin  | admin@example.com        | admin12345    |\n| Editor | editor@example.com       | editor12345   |\n| Viewer | viewer@example.com       | viewer12345   |\n\n---\n\n## Project Structure\n\n```\nportfolio-platform-api/\n├── app/                        # Main application code\n│   ├── api/                    # API routes and dependencies\n│   │   ├── deps.py            # Dependency injection (auth, RBAC)\n│   │   ├── router.py          # Main API router\n│   │   └── routes/            # Route handlers\n│   │       ├── auth.py        # Authentication endpoints\n│   │       ├── users.py       # User management\n│   │       ├── projects.py    # Project CRUD\n│   │       ├── tags.py        # Tag management\n│   │       ├── activity.py    # Audit logs\n│   │       └── orgs.py        # Organization management\n│   ├── core/                   # Core utilities\n│   │   ├── config.py          # Configuration settings\n│   │   └── security.py        # JWT \u0026 password hashing\n│   ├── db/                     # Database configuration\n│   │   ├── base.py            # SQLAlchemy base\n│   │   └── session.py         # Database session\n│   ├── models/                 # SQLAlchemy models\n│   │   ├── user.py            # User model\n│   │   ├── organization.py    # Organization model\n│   │   ├── project.py         # Project model\n│   │   ├── tag.py             # Tag model\n│   │   ├── activity.py        # Activity log model\n│   │   └── enums.py           # Enum definitions (roles)\n│   ├── schemas/                # Pydantic schemas\n│   │   ├── auth.py            # Auth request/response schemas\n│   │   ├── user.py            # User schemas\n│   │   ├── project.py         # Project schemas\n│   │   ├── tag.py             # Tag schemas\n│   │   ├── activity.py        # Activity log schemas\n│   │   └── org.py             # Organization schemas\n│   ├── services/               # Business logic\n│   │   ├── activity_service.py # Activity logging\n│   │   └── tag_service.py     # Tag operations\n│   └── main.py                 # FastAPI application entry point\n├── alembic/                    # Database migrations\n│   ├── versions/              # Migration files\n│   └── env.py                 # Alembic configuration\n├── tests/                      # Test suite\n│   ├── conftest.py            # Pytest fixtures\n│   ├── test_auth.py           # Authentication tests\n│   ├── test_rbac_projects.py  # RBAC tests\n│   ├── test_tags.py           # Tag tests\n│   ├── test_admin.py          # Admin functionality tests\n│   └── test_edge_cases.py     # Edge case tests\n├── scripts/                    # Utility scripts\n│   └── seed_admin.py          # Database seeding\n├── docs/                       # Documentation\n├── .env.example                # Environment variables template\n├── .github/                    # GitHub Actions CI\n├── alembic.ini                 # Alembic configuration\n├── docker-compose.yml          # PostgreSQL container\n├── pytest.ini                  # Pytest configuration\n└── requirements.txt            # Python dependencies\n```\n\n---\n\n## Key Technologies Explained\n\n### FastAPI\n- Modern, high-performance web framework\n- Automatic interactive API documentation (Swagger/ReDoc)\n- Built-in data validation with Pydantic\n- Native async support for better performance\n- Type hints for better IDE support\n\n### JWT Authentication\n- Access tokens (short-lived, 30 min) for API requests\n- Refresh tokens (long-lived, 7 days) for token renewal\n- Secure token-based authentication without server-side sessions\n- Automatic token expiry and refresh mechanism\n\n### SQLAlchemy 2.0\n- Modern ORM with full type hint support\n- Declarative models with relationship mapping\n- Query builder for complex database operations\n- Database-agnostic (PostgreSQL in production, SQLite for tests)\n\n### Alembic\n- Database migration management\n- Version control for database schema\n- Auto-generate migrations from model changes\n- Safe rollback capabilities\n\n### Argon2\n- Memory-hard password hashing algorithm\n- Resistant to GPU-based attacks\n- Winner of the Password Hashing Competition\n- More secure than bcrypt or PBKDF2\n\n### Pytest\n- Powerful testing framework with fixtures\n- Integration testing with FastAPI TestClient\n- In-memory SQLite for fast, isolated tests\n- Coverage reporting for test quality metrics\n\n---\n\n## CI/CD\n\nGitHub Actions automatically:\n- Runs all tests on every push\n- Validates code quality\n- Ensures database migrations are valid\n- Fails build on test failures or errors\n\nSee [Testing \u0026 CI](docs/testing-and-ci.md) for details.\n\n---\n\n## API Documentation\n\nFastAPI provides automatic interactive documentation:\n\n- **Swagger UI**: http://127.0.0.1:8000/docs\n  - Interactive API testing interface\n  - Try out endpoints directly in browser\n  - View request/response schemas\n\n- **ReDoc**: http://127.0.0.1:8000/redoc\n  - Alternative documentation interface\n  - Better for reading and sharing\n\n- **OpenAPI JSON**: http://127.0.0.1:8000/openapi.json\n  - Raw OpenAPI 3.0 specification\n  - Can be imported into Postman, Insomnia, etc.\n\n---\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\nThis project was created for portfolio and educational purposes.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafsanajamal%2Fportfolio-platform-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fafsanajamal%2Fportfolio-platform-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafsanajamal%2Fportfolio-platform-api/lists"}