Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f87a9ea
chore: untrack 5 snapshot JSONs re-committed after 46a731f
K1NGD4VID May 30, 2026
4a0b79e
fix(backend): add missing @vitest/coverage-v8 dev dependency
K1NGD4VID May 30, 2026
127c079
Merge branch 'main' into never-commit-test_snapshots
K1NGD4VID Jun 1, 2026
a135944
Merge branch 'LabsCrypt:main' into never-commit-test_snapshots
K1NGD4VID Jun 1, 2026
b22c8fc
fix(ci): fix malformed package-lock.json and resolve JSDoc YAMLSemant…
K1NGD4VID Jun 1, 2026
15ca84f
merge: resolve conflict in package-lock.json and sync upstream main
K1NGD4VID Jun 1, 2026
712a3e8
fix(frontend): resolve all ESLint warnings and React Compiler memoiza…
K1NGD4VID Jun 2, 2026
1b48187
fix: ensure proper cleanup of SSE events with AbortController
extolkom Jun 2, 2026
7a37285
Update README.md
dorismaduegbunam Jun 2, 2026
471aaf1
chore: replace err any with unknown and narrow safely
dubemoyibe-star Jun 2, 2026
b3a0f64
fix: resolve pagination magic numbers
devfoma Jun 2, 2026
2d8fb7b
Merge pull request #592 from K1NGD4VID/never-commit-test_snapshots
ogazboiz Jun 2, 2026
1c1b636
Merge pull request #736 from dubemoyibe-star/fix/error-middleware-unk…
ogazboiz Jun 2, 2026
3bf9e60
Merge pull request #739 from dorismaduegbunam/fix/pagination-magic-nu…
ogazboiz Jun 2, 2026
361663b
fix: ensure proper cleanup of SSE events with AbortController
extolkom Jun 2, 2026
42180ff
Merge branch 'main' of https://github.com/extolkom/flowfi
extolkom Jun 2, 2026
75d3237
fix: resolve setState in effect eslint error in streams page
extolkom Jun 2, 2026
d037bdf
fix: ensure useEffect returns cleanup in TransactionTracker
extolkom Jun 2, 2026
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

_Programmable, real-time payment streams and recurring subscriptions._

i just need to create a draft pr

## Overview

FlowFi allows users to create continuous payment streams and recurring subscriptions using stablecoins on the Stellar network. By leveraging Soroban smart contracts, FlowFi enables autonomous accurate-to-the-second distribution of funds.
Expand Down
12 changes: 8 additions & 4 deletions backend/src/controllers/stream.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import {
resumeStream as sorobanResumeStream,
} from '../services/sorobanService.js';
import type { AuthenticatedRequest } from '../types/auth.types.js';
import { DEFAULT_EVENTS_PAGE_SIZE, MAX_EVENTS_PAGE_SIZE } from '../routes/v1/events.routes.js';

const DEFAULT_STREAM_PAGE_SIZE = 20;
const MAX_STREAM_PAGE_SIZE = 100;

interface UserStreamSummary {
address: string;
Expand Down Expand Up @@ -170,8 +174,8 @@ export const listStreams = async (req: Request, res: Response) => {

// Validate and parse pagination parameters
const parsedLimit = Math.min(
typeof limit === 'string' ? (Number.parseInt(limit, 10) || 20) : 20,
100
typeof limit === 'string' ? (Number.parseInt(limit, 10) || DEFAULT_STREAM_PAGE_SIZE) : DEFAULT_STREAM_PAGE_SIZE,
MAX_STREAM_PAGE_SIZE
);
const parsedOffset = typeof offset === 'string' ? (Number.parseInt(offset, 10) || 0) : 0;

Expand Down Expand Up @@ -285,8 +289,8 @@ export const getStreamEvents = async (req: Request, res: Response) => {
const eventType = typeof req.query['eventType'] === 'string' ? req.query['eventType'] : undefined;

const limit = Math.min(
rawLimit && typeof rawLimit === 'string' ? (Number.parseInt(rawLimit, 10) || 50) : 50,
500,
rawLimit && typeof rawLimit === 'string' ? (Number.parseInt(rawLimit, 10) || DEFAULT_EVENTS_PAGE_SIZE) : DEFAULT_EVENTS_PAGE_SIZE,
MAX_EVENTS_PAGE_SIZE,
);

let offset = 0;
Expand Down
5 changes: 3 additions & 2 deletions backend/src/controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { prisma } from '../lib/prisma.js';
import logger from '../logger.js';
import { registerUserSchema } from '../validators/user.validator.js';
import type { AuthenticatedRequest } from '../types/auth.types.js';
import { DEFAULT_EVENTS_PAGE_SIZE, MAX_EVENTS_PAGE_SIZE } from '../routes/v1/events.routes.js';

/**
* Register a new wallet public key
Expand Down Expand Up @@ -81,8 +82,8 @@ export const getUserEvents = async (req: Request, res: Response, next: NextFunct
const rawOffset = req.query['offset'];

const limit = Math.min(
rawLimit && typeof rawLimit === 'string' ? (Number.parseInt(rawLimit, 10) || 50) : 50,
200
rawLimit && typeof rawLimit === 'string' ? (Number.parseInt(rawLimit, 10) || DEFAULT_EVENTS_PAGE_SIZE) : DEFAULT_EVENTS_PAGE_SIZE,
MAX_EVENTS_PAGE_SIZE
);
const offset = rawOffset && typeof rawOffset === 'string' ? (Number.parseInt(rawOffset, 10) || 0) : 0;

Expand Down
18 changes: 9 additions & 9 deletions backend/src/middleware/error.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { Request, Response, NextFunction } from 'express';
import { Prisma } from '../generated/prisma/index.js';
import { ZodError } from 'zod';
import { ZodError, type ZodIssue } from 'zod';
import logger from '../logger.js';

/**
* Global error handler middleware
*/
export const errorHandler = (
err: any,
err: unknown,
req: Request,
res: Response,
next: NextFunction
Expand All @@ -18,7 +18,7 @@ export const errorHandler = (
if (err instanceof ZodError) {
return res.status(400).json({
error: 'Validation Error',
details: err.issues.map((e: any) => ({
details: err.issues.map((e: ZodIssue) => ({
path: e.path.join('.'),
message: e.message
}))
Expand All @@ -28,26 +28,26 @@ export const errorHandler = (
// Handle Prisma Errors
if (err instanceof Prisma.PrismaClientKnownRequestError) {
// Unique constraint violation
if (err.code === 'P2002') {
const target = (err.meta?.target as string[])?.join(', ') || 'field';
if ((err as Prisma.PrismaClientKnownRequestError).code === 'P2002') {
const target = ((err as Prisma.PrismaClientKnownRequestError).meta?.target as string[])?.join(', ') || 'field';
return res.status(409).json({
error: 'Conflict Error',
message: `Record with this ${target} already exists.`
});
}

// Record not found
if (err.code === 'P2025') {
if ((err as Prisma.PrismaClientKnownRequestError).code === 'P2025') {
return res.status(404).json({
error: 'Not Found',
message: err.message || 'The requested record was not found.'
message: (err as Prisma.PrismaClientKnownRequestError).message || 'The requested record was not found.'
});
}
}

// Default Error
const statusCode = err.status || err.statusCode || 500;
const message = err.message || 'Internal Server Error';
const statusCode = (err instanceof Error && (err as any).status) || (err instanceof Error && (err as any).statusCode) || 500;
const message = err instanceof Error ? err.message : 'Internal Server Error';

res.status(statusCode).json({
error: statusCode === 500 ? 'Internal Server Error' : 'Error',
Expand Down
8 changes: 4 additions & 4 deletions backend/src/routes/v1/events.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const EVENT_TYPES = new Set([
'ADMIN_TRANSFERRED',
]);

const MAX_EVENT_LIMIT = 200;
const DEFAULT_EVENT_LIMIT = 50;
export const MAX_EVENTS_PAGE_SIZE = 200;
export const DEFAULT_EVENTS_PAGE_SIZE = 50;

/**
* @openapi
Expand Down Expand Up @@ -86,8 +86,8 @@ router.get('/', async (req: Request, res: Response, next: NextFunction) => {

const parsedLimit = Number.parseInt(String(req.query.limit ?? ''), 10);
const limit = Number.isFinite(parsedLimit) && parsedLimit > 0
? Math.min(parsedLimit, MAX_EVENT_LIMIT)
: DEFAULT_EVENT_LIMIT;
? Math.min(parsedLimit, MAX_EVENTS_PAGE_SIZE)
: DEFAULT_EVENTS_PAGE_SIZE;

const hasOffset = req.query.offset !== undefined;
const parsedOffset = Number.parseInt(String(req.query.offset ?? ''), 10);
Expand Down
Loading
Loading