Building Portfolio Projects Beyond CRUD Operations

Many portfolio projects stop at basic CRUD (Create, Read, Update, Delete) functionality. This post documents how to build projects with richer features: transaction management, authentication, event processing, integration testing, and containerization—all of which demonstrate deeper engineering skills to potential employers.

Project Requirements

A portfolio project should go beyond a simple to-do list or note-taking app. Requirements should include: multi-tenant data isolation, role-based access control, event-driven workflows, and export/import functionality. These features demonstrate the ability to build software that is secure, scalable, and maintainable.

Architecture & Data Modeling

The project uses a modular architecture with separate modules for core, auth, billing, and reporting. Data modeling includes relational tables with proper foreign keys, indexes for query performance, and migration scripts. Entity-relationship diagrams are generated using SQLModel and Alembic for versioned schema changes.

Error Handling

A custom exception hierarchy handles expected and unexpected errors:

class AppError(Exception):
    status_code = 400
    def __init__(self, message, status_code=None, payload=None):
        super().__init__(message)
        if status_code is not None:
            self.status_code = status_code
        self.payload = payload

All endpoints wrap return values in a consistent JSON format: {"success": bool, "data": ..., "error": {...}}.

Authentication

JWT-based authentication with refresh/access token flow. Passwords are hashed using bcrypt. Token expiration is 15 minutes for access tokens and 7 days for refresh tokens. Protected endpoints use a decorator: @auth_required.

Event Processing

Kafka is used to publish domain events: UserRegistered, PaymentCompleted, and PasswordResetRequested. A consumer service listens and triggers side effects: sending welcome emails, updating analytics, and generating reset links.

Testing

Integration tests cover the full request lifecycle: authentication, event production, and consumer processing. Testcontainers spin up a Kafka broker and PostgreSQL instance. Unit tests use pytest with parameterized inputs for error handling paths.

Deployment

The project is containerized with Docker Compose: a web service, PostgreSQL, and Kafka broker. CI/CD pipeline uses GitHub Actions to run tests on every push and deploy the Docker image to DigitalOcean App Platform on merge.

Repository Evidence

Project source code is published on GitHub with a README that includes:

A.M. Rinas

Written by A.M. Rinas

Full-Stack Software Engineer working on web applications, DevOps automation, and databases. More about me on the about page, or say hi through the contact page and LinkedIn.

← Back to all articles

A.M. Rinas

Written by A.M. Rinas

Full-Stack Software Engineer working on web applications, DevOps automation, and databases. More about me on the about page, or say hi through the contact page and LinkedIn.

← Back to all articles