commit eefe4dfcc2baa14842cbb06ee8a9e2ce7883ab6f Author: Jeff Emmett Date: Thu Jan 29 17:56:07 2026 +0000 Initial commit: Flow Funding project setup - Next.js 14 with TypeScript and Tailwind CSS - React Flow / D3.js for flow visualizations - Docker + Traefik labels for deployment at flowidity.io/tbff - Basic project structure and placeholder page Co-Authored-By: Claude Opus 4.5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..80339e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Dependencies +node_modules/ +.pnpm-store/ + +# Next.js +.next/ +out/ + +# Build +dist/ +build/ + +# Environment +.env +.env.local +.env.*.local + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# TypeScript +*.tsbuildinfo +next-env.d.ts diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b99fe11 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM node:20-alpine AS base + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Dependencies stage +FROM base AS deps +WORKDIR /app +COPY package.json pnpm-lock.yaml* ./ +RUN pnpm install --frozen-lockfile || pnpm install + +# Build stage +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . +RUN pnpm build + +# Production stage +FROM base AS runner +WORKDIR /app +ENV NODE_ENV=production + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs +EXPOSE 3000 +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +CMD ["node", "server.js"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..22ef26a --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# Flow Funding + +Visual interactive interface for threshold-based flow funding mechanisms. + +## Concept + +Flow funding enables continuous, threshold-based resource allocation where: +- Funds flow continuously rather than in discrete grants +- Thresholds determine when funding activates/deactivates +- Visual interfaces make the system intuitive and transparent + +## Features (Planned) + +- **Interactive Flow Visualization**: Real-time display of funding flows between sources and recipients +- **Threshold Configuration**: Visual tools to set and adjust funding thresholds +- **Flow Dynamics**: Animate how funds move when thresholds are met +- **Dashboard**: Overview of all active flows, thresholds, and balances + +## Tech Stack + +- Next.js 14 (App Router) +- React Flow / D3.js for flow visualizations +- Tailwind CSS for styling +- TypeScript + +## Development + +```bash +pnpm install +pnpm dev +``` + +## Deployment + +Dockerized for deployment on Netcup RS 8000 via Traefik. + +**URL**: `https://flowidity.io/tbff` + +```bash +docker compose up -d --build +``` + +## License + +MIT diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..ed4de77 --- /dev/null +++ b/app/globals.css @@ -0,0 +1,20 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --foreground-rgb: 0, 0, 0; + --background-rgb: 255, 255, 255; +} + +@media (prefers-color-scheme: dark) { + :root { + --foreground-rgb: 255, 255, 255; + --background-rgb: 10, 10, 10; + } +} + +body { + color: rgb(var(--foreground-rgb)); + background: rgb(var(--background-rgb)); +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..a88e471 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,21 @@ +import type { Metadata } from 'next' +import './globals.css' + +export const metadata: Metadata = { + title: 'Flow Funding', + description: 'Visual interactive interface for threshold-based flow funding', +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + {children} + + + ) +} diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 0000000..177d2dd --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,21 @@ +'use client' + +export default function Home() { + return ( +
+
+

+ Flow Funding +

+

+ Visual interactive interface for threshold-based flow funding mechanisms +

+
+

+ Interactive visualization coming soon... +

+
+
+
+ ) +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b1de5ba --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +services: + flow-funding: + build: . + restart: unless-stopped + environment: + - NEXT_PUBLIC_BASE_PATH=/tbff + labels: + - "traefik.enable=true" + - "traefik.http.routers.flow-funding.rule=Host(`flowidity.io`) && PathPrefix(`/tbff`)" + - "traefik.http.routers.flow-funding.middlewares=flow-funding-stripprefix" + - "traefik.http.middlewares.flow-funding-stripprefix.stripprefix.prefixes=/tbff" + - "traefik.http.services.flow-funding.loadbalancer.server.port=3000" + networks: + - traefik-public + +networks: + traefik-public: + external: true diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..ce733a6 --- /dev/null +++ b/next.config.js @@ -0,0 +1,8 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + output: 'standalone', + basePath: process.env.NEXT_PUBLIC_BASE_PATH || '', + assetPrefix: process.env.NEXT_PUBLIC_BASE_PATH || '', +} + +module.exports = nextConfig diff --git a/package.json b/package.json new file mode 100644 index 0000000..75dc6f0 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "flow-funding", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "next": "^14.2.0", + "react": "^18.3.0", + "react-dom": "^18.3.0", + "@xyflow/react": "^12.0.0", + "d3": "^7.9.0" + }, + "devDependencies": { + "@types/d3": "^7.4.0", + "@types/node": "^20.0.0", + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", + "autoprefixer": "^10.4.0", + "postcss": "^8.4.0", + "tailwindcss": "^3.4.0", + "typescript": "^5.0.0" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..e980129 --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,23 @@ +import type { Config } from 'tailwindcss' + +const config: Config = { + content: [ + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './app/**/*.{js,ts,jsx,tsx,mdx}', + ], + theme: { + extend: { + colors: { + flow: { + primary: '#3B82F6', + secondary: '#10B981', + accent: '#8B5CF6', + threshold: '#F59E0B', + }, + }, + }, + }, + plugins: [], +} +export default config diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e7ff90f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +}