FinTech / Selected work

    The foundations for a new kind of investing.

    Backend development for a platform connecting founders and investors.

    All work
    Client
    MicroFundry Inc.
    Our contribution
    Platform development
    Focus
    Crowdfunding infrastructure
    MicroFundry equity crowdfunding platform
    MicroFundry Inc. / Product overviewView full image ↗

    A platform with several moving parts

    MicroFundry brings together campaigns, investor activity, founder uploads, and administrative workflows. Our contribution focused on the backend that connects these parts.

    The work separated routes, controllers, services, and repositories so changes to one area could be understood and tested more clearly.

    Uploads built for the environment

    Pitch decks and campaign media need a different path from ordinary API requests. Direct uploads to S3 use presigned URLs, allowing files to reach storage without passing through the application's request body.

    Keeping financial operations together

    Investment and withdrawal workflows use database transactions to group related changes. Administrative actions are recorded alongside the workflow, giving the team a history to refer to.

    Scheduled operations handle recurring work such as checking campaign dates. The resulting structure gives the team a clearer place to add and maintain product features.

    A closer look

    From the overview
    to the details.

    Engineering decisions

    Considered beneath
    the surface.

    01

    Layered Serverless Architecture

    Migrating from a monolith to a clean MVC-like pattern (Routes → Controllers → Services → Repositories).

    02

    Secure Financial Workflows

    Building atomic, transactional logic for investments, withdrawals, and referral payouts to ensure data integrity.

    03

    Direct-to-Cloud Uploads

    Implementing S3 presigned URLs to bypass serverless limitations and enable large, secure media uploads.

    Explore an implementation detail — withdrawalService.ts
    public async processWithdrawal(adminId: string, withdrawalId: number, status: "approved" | "rejected", notes: string) {
        return db.transaction(async (tx) => {
            // 1. Verify the request is valid and pending
            const withdrawal = await this.userRepo.findWithdrawalById(withdrawalId, tx);
            if (!withdrawal || withdrawal.status !== "pending") {
                throw new AppError("Request not found or already processed.", 404);
            }
    
            // 2. Update status and log the admin's action for audit trail
            const updated = await this.userRepo.updateWithdrawalRequest(withdrawalId, { status, adminNotes: notes }, tx);
            await this.adminRepo.createAdminLog(adminId, `withdrawal_${status}`, { notes }, tx);
            
            // 3. Notify the founder
            await this.notificationService.createInAppNotification({ /* ... */ }, tx);
            
            return updated;
        });
    }
    

    Another piece of work

    Vertebra

    Explore the project

    A good place to begin

    What are you
    working on?

    A new idea, an existing product,
    or a problem worth solving.

    Let's talk