🐈
立て替えの取引回数を最小限にするtatekaeというサービスを作成しました!
背景
僕を含めた友達でよく旅行に行くのですが、旅行に付きまとうのは代金の立て替えだと思います。
飛行機代を建て替えたり、居酒屋代を建て替えたりと色々立て替えることが多いですが、必ずしも一人が建て替え続けることは少ないと思います。
また個々に建て替えたりと、旅行のたびに請求したりされたりで面倒だったので、作成に至りました。
repository:
使い方
立て替えの取引を他人見られても問題ない人やデモを見てみたい人は、下記のURL(自宅サーバ)に公開しています。時々閉じていたりするので、注意してもらえるとありがたいです。
起動方法
k8sなどに3つコンテナを作成します。dbは、mysqlのimageを使用し、apiとwebはghcrから取得してください。
- docker compose
docker-compose.yml
services:
db:
image: mysql:8.1
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: password
ports:
- "3306:3306"
volumes:
- db:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 5s
retries: 5
api:
image: ghcr.io/ei-sugimoto/tatekae/api:latest
ports:
- "8080:8080"
environment:
- DB_HOST=xxx
- DB_USER=xxx
- DB_PASS=xxx
- DB_NAME=xxx
- DB_PORT=3306
depends_on:
db:
condition: service_healthy
tty: true
web:
image: ghcr.io/ei-sugimoto/tatekae/api:latest
ports:
- "3000:80"
depends_on:
- api
- db
tty: true
working_dir: /workspace/app
stdin_open: true
- k8s
tatekae-deploy.yml
apiVersion: v1
kind: Namespace
metadata:
name: tatekae
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-pvc
namespace: tatekae
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: db
namespace: tatekae
spec:
ports:
- port: 3306
selector:
app: db
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
namespace: tatekae
spec:
replicas: 1
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: mysql:8.1
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: 'xxxx'
- name: MYSQL_DATABASE
value: 'xxxx'
- name: MYSQL_USER
value: 'xxxx'
- name: MYSQL_PASSWORD
value: 'xxxx'
volumeMounts:
- name: db-storage
mountPath: /var/lib/mysql
volumes:
- name: db-storage
persistentVolumeClaim:
claimName: db-pvc
---
apiVersion: v1
kind: Service
metadata:
name: api
namespace: tatekae
spec:
ports:
- port: 8080
selector:
app: api
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: tatekae
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: ghcr.io/ei-sugimoto/tatekae/api:latest
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: 'xxxx'
- name: DB_USER
value: 'xxxx'
- name: DB_PASS
value: 'xxxx'
- name: DB_NAME
value: 'xxxx'
- name: DB_PORT
value: '3306'
volumeMounts:
- name: api-storage
mountPath: /app
volumes:
- name: api-storage
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: tatekae
spec:
ports:
- port: 3000
targetPort: 80
selector:
app: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: tatekae
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: ghcr.io/ei-sugimoto/tatekae/web:latest
ports:
- containerPort: 80
volumeMounts:
- name: web-storage
mountPath: /workspace/app
volumes:
- name: web-storage
emptyDir: {}
サイト内説明
- ユーザにログインまたは登録
まずは、ユーザを作成またはログインをしましょう!
- プロジェクトを作成および参加
旅行毎にプロジェクトを作成しましょう!作成したら、Joinボタンを押して参加しましょう。
- 請求を作成する
赤がプロジェクト名、青が参加しているメンバー、黄が請求を作成するところです。
参加しているメンバーが請求先一覧に表示されるので、建て替えた金額を入力し、請求先を作成しましょう!
作成が完了すると、作成した請求の一覧と、取引回数を最小限した結果を示すsummarizeが表示されます。
技術スタック
api
- ent
entを使用してschemaからテーブルを作成しています。また、SQLに型の注釈がつくので非常に簡単です。 - connect-go
gprc通信およびwebからのhttp通信の両方に対応でき、protobufでエンドポイントやリクエストレスポンスを定義できるconnectを使用しました。
これにより、リクエスト等にも型の注釈がつくので、楽に開発できました。
web
- vite+react
ビルドツールとしてvite、また純粋なreactを採用しました。vueとreactは迷いましたが、最近使っているreactを選びました。
other
-
cloudflared tunnel
サクッと自宅サーバを構築できます。デモサイトもtunnelを作成して、自宅サーバとして公開しています。このtunnel自体もコンテナを起動することで簡単に作成できるのでまじで便利です!!
今後追加していきたい機能
- プロジェクトをpublicかprivateかを選べる
現状では、すべてのプロジェクトが見れるようになっているので、招待制のプロジェクトも作成できるようにしていきたいです。 - UIを作りこむ
まだ、1週間程度しか開発していないので、UIが微妙です。ここは少しずつ作りこんでいきたい。
Discussion