Skip to content

orangzz/fintech-transaction

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

end to end type safe with hono and zod

  • Ultrafast and lightweight
  • Fully typed and clean APIs
  • run on edge(cloudflare workers,AWS Lambda) or serverless runtime(netlify),Deno, Bun and Node
  • sharing of the API specifications between the server and the client.

InferResponseType, InferRequestType

# state a project with hono template
bun create hono@latest <app>
# or add hono to existing project
bun add hono @hono/zod-validator zod
bnn add @hono/clerk-auth @clerk/backend

inferred the path parameter

zod - compile time type infer w/ runtime type checking you ever could ask about API Response

Defines the shape of data queried from the database or validate API requests.

// cookie form header json param query zValidator('')

Format before commit

# add exact version over range
bun add --dev --exact eslint-config-prettier prettier husky lint-staged
bun add --dev eslint typescript-eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser
bunx husky init
bun --eval "fs.writeFileSync('.husky/pre-commit','bunx lint-staged\n')"

Features

each features are co-location for maintainability, layer of abstraction and Sensibility

  • features
    • /api: query client
    • /components: query UI
    • /hooks: state hooks

account management transaction History management

transaction history management query,filter,add or edit transaction

if selected,disable if deselected, enable

dashboard.overview subscription and paywall

// array of object → fields-data object
const objectsToFieldsData = (arr: ObjectArray): FieldsData => {
  if (!arr.length) return { fields: [], data: [] };
  const fields = Object.keys(arr[0]);
  return {
    fields,
    data: arr.map(obj => fields.map(key => obj[key]))
  };
};

// field-data object to array of object
const fieldsDataToObjects = ({ fields, data }: FieldsData): ObjectArray =>
  data.map(row =>
    fields.reduce((obj, key, i) => ({ ...obj, [key]: row[i] }), {})
  );



// Object Array → Array of Arrays
const objectsToArrays = (arr: ObjectArray): ArrayOfArrays =>
  [Object.keys(arr[0]), ...arr.map(obj => Object.values(obj))]


// Array of Arrays → Object Array
const arraysToObjects = (arr: ArrayOfArrays): ObjectArray => {
  const [fields, ...data] = arr;
  return data.map(row =>
    fields.reduce((obj, key, i) => ({ ...obj, [key]: row[i] }), {})
  );
};

array of object

[
	{
		"Column 1": "foo",
		"Column 2": "bar"
	},
	{
		"Column 1": "abc",
		"Column 2": "def"
	}
]

field-data obejct

{
	"fields": ["Column 1", "Column 2"],
	"data": [
		["foo", "bar"],
		["abc", "def"]
	]
}

array of array

[
	["Column 1", "Column 2"],
	["foo", "bar"],
	["abc", "def"]
]

view-transiation api

Tip

有些api要在pull request中找到用例 - not yet documented colinhacks/zod#3415

z.extend z.remap z.mergei

parse dateStr to Date object, or format Date object to dateStr. ISO 8601格式是“YYYY-MM-DDTHH:mm:ss”

query-string - power parsing and stringify API feature and clarify documented

Drizzle-ORM

# file runner
bun app/index.ts
# script runner
bun db:generate #  script ->  "db:generate": "drizzle-kit generate --config drizzle.config.ts",
#  equivalent package executable runner
bunx drizzle-kit generate --config drizzle.config.ts

drizzle-rom

drizzle-kit generate

drizzle-kit migrate

drizzle-kit studio

drizzle-kit seed

it ensures that the data you generate is consistent and reproducible across different runs.

weighted random distribution

refinee with range

count: number of rows to insert

with

columns

await seed(db,schema).refine((f) => ({
  users: {
    count:5,
    // refien between range
    columns: {
        id: f.int({
          minValue: 1000,
          maxValue: 2000,
          isUnique: true
        })
    }
  },
  posts: {
    count: 100,
      // refine to retrive value from self-provided array
    columns: {
      description: f.valueFromArrary({
        values: [

        ]
      })
    }
  }.
   phoneNumber: funcs.phoneNumber({
        template: "+(380) ###-####",
         prefixes: ["+380 99", "+380 67"],
         generatedDigitsNumbers: 7,
        arraySize: 3
      }),
}))

data analyst

business intelligence/analyst

type safe UI compoennt

cva

npm i cva@npm:class-variance-authority
import { cva } from "cva";

UML: Devloping APPlciatin using Model

  • sequence digram
  • component digram
  • class digram
  • Gitflow diagram
  • Kanban boards
  • dependency graph

DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。 VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。 DAO (Data Access Object ) 数据访问对象 BO(Business Object):业务对象,由 Service 层输出的封装业务逻辑的对象。 DO(Data Object):此对象的属性与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。

system sequence diagrams,

  • order
  • involved party/particiant
  • cross system boundaries

the power the batch

lifeline activation Bar selft call shape The Callback shape (dispatch-return)

Deploy

Deploy platform choice

netlify vercel render.com cloudfare worker fly.io

Deploy config

deploy platform expect build scripts and start start scripts

{
  "scripts": {
    "build" : "tsc  && tsc-alias",
    "start" : "node dist",
    "vercel:preview:": "vercel:preview"
  }
}

Vercel

glob pattern

api/*.js (matches all js files under all current direcotry) api/**/*.ts (matches all ts files under any level subDirecoty) api/**/* (matches all files under any level subDirecotry) /(.*): any filename

  • severless Functions support runtime Node.js, Python, Go, Edge

  • static assets

  • install command:

  • build command:

  • output Drecotory

  • public Directory

  • root Directory

{
  "buildCommand": "next build",
  // "rewrites": [{"source" : "/(.*)", "destination": "/api"}]
  "rewrites": [
    {
      "source": "/api/:path",
      "destination": "https://api.example.com/:path"
    },
    {
      "source": "/resize/:width/:height",
      "destination": "/api/sharp"
    }
  ]
}

Hono

queryClient

inferType from db schema

import {handle} from "hono/vercel"
export const = "edge"
import app from "../dist/app.js"

read the env

import {
  createInsertSchema,
  createSelectSchema
}  from "drizzle-zod"
export const InsertUserSchema =
  createInertSchema(schema.users, {
    email: (schema) => schema.email.email()
  })
    .omit({
      id: true,
      createAt: true
    })
    .openapi(""Inser Users)

expor type InsertUserSchema = z.infer<
  typeof InsertUserSchema
>

DB coonection

dbCredentials: {
    url: process.env.DATABASE_URL!
  }
dbCredentails to connect database
# connection rul w/ username, passwd
# connection url w/ auth token
DATABSE_AUTH_TOKEN=
DATABASE_URL=

build before deploy

tsx: ts file executor - transiple file just in time and run it throught nodejs

using tsup or native tsc compiler to compile .ts file to .js file

build esm requres resolve full path

esm dont't handle node-like module reoslution

LOAD_AS_FILE(X)
LOAD_INDEX(X)
LOAD_AS_DIRECTORY(X)

lib that handle esm-import-alias

{
  "scripts": {"build": "tsc && tsc-alias"}
}
{
  "tsc-alias" : {
    "resolveFullPath": true,
    "outDir": "./dist", // ".lib"
    "declarationDir": "./dists/types",
    "watch": true
  }
}

lib that hanlder esm-auto-import/esm-import-directory

URL

ES modules are resolved and cached as URLs

Percent-encoding

URLs are permiited to only certain range of characters any char failling outside of that allow range must be encoding

URL schema

node:URLs load Node.js builtin modules data:URLs, URLs prefixed with the data: scheme, file: URLs

module metadata info injection

A module namespace object is an object that describes all exports from a module access the module namespace object of a module: through a namespace import (import * as name from moduleName), or through the fulfillment value of a dynamic import.

rqurie module resoultion

require(X) from module at path Y
1. If X is a core/bare module,
   a. return the core module
   b. STOP
2. If X begins with '/'
   a. set Y to the file system root
3. If X begins with './' or '/' or '../'
   a. LOAD_AS_FILE(Y + X)
   b. LOAD_AS_DIRECTORY(Y + X)
   c. THROW "not found"
4. If X begins with '#'
   a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))

load esm using require (cjs consumer)

class noc{}
function nof () {}
module.exports = {
  default: noc
  not: nof,

}

// [Module: null prototype] {
//   distance: [Function: distance]
// }

const point = require('./point.mjs');
console.log(point);
// [Module: null prototype] {
//   default: [class Point],
//   __esModule: true,
// }
import.meta.resolve('../vite.config.ts') // => "file://path/to/base/vite.config.ts"
import.meta.resolve("zod"); // => "file:///path/to/project/node_modules/zod/index.js"

// Resolve a module specifier (e.g. "zod" or "./file.tsx", "../vite.config.ts") to a string url
import.meta.resolve
import.meta.url	// A file url to the current mod, like 'file:///path/to/project/index.ts'

// bun runtime injection
import.meta.dir   // 	Absolute path to the directory containing the current file
 import.meta.path	 // Absolute path to the current file

// node runtime jnjection
 import.meta.dirname
 import.meta.filename

Self-hosting

# Download the deployment script:
curl -o ~/deploy.sh https://github.com/0x3f1opusexpavotelos/finance-sass/deploy.sh
# Run the deployment script:
chmod +x ~/deploy.sh
./deploy.sh

Helpful Commands

  • docker-compose ps – check status of Docker containers
  • docker-compose logs web – view Next.js output logs
  • docker-compose logs cron – view cron logs
  • docker-compose down - shut down the Docker containers
  • docker-compose up --build -d - start containers in the background
  • sudo systemctl restart nginx - restart nginx
  • docker exec -it myapp-web-1 sh - enter Next.js Docker container
  • docker exec -it myapp-db-1 psql -U myuser -d mydatabase - enter Postgres db

secerts cross env management

// merge the env
app.use((c, next) => {
  c.env = Object.assign(c.env, process.env)
  return next
})
// switch to production API endpoint
app.use((c,next) => {
  if(c.env.NODE_ENV === "production") {
    const domain = "https://finance.ransom.tech"
    c.env.NEXT_PUBLIC_URL=domain
  }
})

Hard code secrets in your app

manual switch with .env.example

push to secret valut secrets, certificates, SSH keys managmen across team and infra

env encryption

encrypt variable .env file and push to git

inject/loads environment variables from a .env file into process.env

as libray require('dotenv').config() or as cli dotenvx run -f -- <command>

dotenvx run -f $project_deploy_conf_dir/.env -- docker compose up --build

enterpriese secret manager - scaleway

scwsm provider: Scaleway Secret Manager awssm provider: AWS Secrets Manager azkv provider: Azure Key Vault gcpsm provider: GCP Secret Manager

team, project, infra scope env variable

Encrypted Environment Variables Cross-Platform and Cross-Framework Compatibility: Multi-Environment Support

PM2, Node Cluster, or Neither in Kubernetes?

PATH:Dockerfile RUN bun install -g pm2

payment api

purchase one-off and subscription products a hosted checkout, which loads the checkout in a browser window, or our checkout overlay, checkout flow pre-filled Checkout fields

https://[STORE].lemonsqueezy.com/checkout/buy/[VARIANT_ID]
?checkout[email][email protected]
&checkout[name]=John Doe
&checkout[billing_address][country]=US
&checkout[billing_address][state]=NY
&checkout[billing_address][zip]=10121
&checkout[tax_number]=123456789
&checkout[discount_code]=10PERCENTOFF

If you are using API to create checkouts pass a JSON object inside checkout_data.

curl -X "POST" "https://api.lemonsqueezy.com/v1/checkouts" \
     -H 'Accept: application/vnd.api+json' \
     -H 'Content-Type: application/vnd.api+json' \
     -H 'Authorization: Bearer {api_key}' \
     -d '{
  "data": {
    "type": "checkouts",
    "attributes": {
      "checkout_data": {
        "email": "[email protected]",
        "name": "John Doe"
      }
    },
    "relationships": {
      ...
    }
  }
}'

const FQDN = ${process.env.NEXT_PUBLIC_APP_URL}

About

fintech transaction workable sass

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages