Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 9 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,23 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up pnpm
uses: pnpm/action-setup@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
node-version: 22
cache: 'pnpm'

- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile

- name: Lint
run: npm run lint
run: pnpm run lint

- name: Build
run: npm run build
run: pnpm run build

- name: Backend integration tests
run: npm run test:backend:int
run: pnpm run test:backend:int
11 changes: 7 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@ jobs:
with:
ref: ${{ github.event.workflow_run.head_sha }}

- name: Set up pnpm
uses: pnpm/action-setup@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
node-version: 22
cache: 'pnpm'

- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile

- name: Build frontend
env:
DATABASE_URL: "postgresql://dummy:dummy@localhost:5432/dummy"
DIRECT_URL: "postgresql://dummy:dummy@localhost:5432/dummy"
run: npm run build --filter=frontend
run: pnpm --filter frontend build

- name: Deploy Frontend to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
Expand Down
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Flat node_modules required by Metro/React Native.
node-linker=hoisted
3 changes: 2 additions & 1 deletion apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dev": "tsx watch src/server.ts",
"prisma": "prisma",
"seed": "tsx --env-file=.env ./prisma/seed.ts",
"db:reset": "prisma migrate reset --force --skip-seed && npm run seed",
"db:reset": "prisma migrate reset --force --skip-seed && pnpm seed",
"studio": "prisma studio",
"build": "prisma generate && tsc",
"test": "jest --config ./jest.config.cjs --runInBand",
Expand Down Expand Up @@ -37,6 +37,7 @@
"@types/node": "^24.10.0",
"bcrypt": "^6.0.0",
"cors": "^2.8.5",
"dotenv": "^17.4.2",
"express": "^5.1.0",
"jsonwebtoken": "^9.0.2",
"pg": "^8.21.0",
Expand Down
4 changes: 2 additions & 2 deletions apps/backend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
// and npm install -D @types/node
// Other Outputs
"sourceMap": false,
"declaration": true,
"declarationMap": true,
"declaration": false,
"declarationMap": false,
// Stricter Typechecking Options
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/modules/AllCrypto/all-crypto.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const CoinSchema = z.object({
sparkline_in_7d: z.object({
price: z.array(z.number()),
}),
other: z.any(),
other: z.any().optional(),
});

export type Coin = z.infer<typeof CoinSchema>;
4 changes: 2 additions & 2 deletions apps/frontend/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"target": "ES2022",
"useDefineForClassFields": true,
"lib": [
"ES2020",
"ES2022",
"DOM",
"DOM.Iterable"
],
Expand Down
43 changes: 43 additions & 0 deletions apps/mobile/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts

# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

app-example

# generated native folders
/ios
/android
48 changes: 48 additions & 0 deletions apps/mobile/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"expo": {
"name": "mobile",
"slug": "mobile",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "mobile",
"userInterfaceStyle": "automatic",
"newArchEnabled": true,
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"backgroundColor": "#E6F4FE",
"foregroundImage": "./assets/images/android-icon-foreground.png",
"backgroundImage": "./assets/images/android-icon-background.png",
"monochromeImage": "./assets/images/android-icon-monochrome.png"
},
"edgeToEdgeEnabled": true,
"predictiveBackGestureEnabled": false
},
"web": {
"output": "static",
"favicon": "./assets/images/favicon.png"
},
"plugins": [
"expo-router",
[
"expo-splash-screen",
{
"image": "./assets/images/splash-icon.png",
"imageWidth": 200,
"resizeMode": "contain",
"backgroundColor": "#ffffff",
"dark": {
"backgroundColor": "#000000"
}
}
]
],
"experiments": {
"typedRoutes": true,
"reactCompiler": true
}
}
}
12 changes: 12 additions & 0 deletions apps/mobile/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Stack } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
import 'react-native-reanimated';

export default function RootLayout() {
return (
<>
<Stack />
<StatusBar style="auto" />
</>
);
}
16 changes: 16 additions & 0 deletions apps/mobile/app/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { StyleSheet, Text, View } from 'react-native';

export default function Home() {
return (
<View style={styles.container}>
<Text style={styles.title}>CoinRadar</Text>
<Text style={styles.subtitle}>Mobile — clean start</Text>
</View>
);
}

const styles = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
title: { fontSize: 28, fontWeight: '600' },
subtitle: { marginTop: 8, opacity: 0.6 },
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/mobile/assets/images/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/mobile/assets/images/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/mobile/assets/images/splash-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions apps/mobile/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// https://docs.expo.dev/guides/using-eslint/
const { defineConfig } = require('eslint/config');
const expoConfig = require('eslint-config-expo/flat');

module.exports = defineConfig([
expoConfig,
{
ignores: ['dist/*'],
},
]);
15 changes: 15 additions & 0 deletions apps/mobile/metro.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Monorepo: resolve deps from both local and workspace-root node_modules.
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');

const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, '../..');

const config = getDefaultConfig(projectRoot);
config.watchFolders = [workspaceRoot];
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, 'node_modules'),
path.resolve(workspaceRoot, 'node_modules'),
];

module.exports = config;
46 changes: 46 additions & 0 deletions apps/mobile/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "mobile",
"main": "expo-router/entry",
"version": "1.0.0",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"lint": "expo lint"
},
"dependencies": {
"@expo/vector-icons": "^15.0.3",
"@react-navigation/bottom-tabs": "^7.4.0",
"@react-navigation/elements": "^2.6.3",
"@react-navigation/native": "^7.1.8",
"expo": "~54.0.35",
"expo-constants": "~18.0.13",
"expo-font": "~14.0.12",
"expo-haptics": "~15.0.8",
"expo-image": "~3.0.11",
"expo-linking": "~8.0.12",
"expo-router": "~6.0.24",
"expo-splash-screen": "~31.0.13",
"expo-status-bar": "~3.0.9",
"expo-symbols": "~1.0.8",
"expo-system-ui": "~6.0.9",
"expo-web-browser": "~15.0.11",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-native": "0.81.5",
"react-native-gesture-handler": "~2.28.0",
"react-native-worklets": "0.5.1",
"react-native-reanimated": "~4.1.1",
"react-native-safe-area-context": "~5.6.0",
"react-native-screens": "~4.16.0",
"react-native-web": "~0.21.0"
},
"devDependencies": {
"@types/react": "~19.1.0",
"typescript": "~5.9.2",
"eslint": "^9.25.0",
"eslint-config-expo": "~10.0.0"
},
"private": true
}
17 changes: 17 additions & 0 deletions apps/mobile/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true,
"paths": {
"@/*": [
"./*"
]
}
},
"include": [
"**/*.ts",
"**/*.tsx",
".expo/types/**/*.ts",
"expo-env.d.ts"
]
}
Loading
Loading