1 Commits

Author SHA1 Message Date
talksik 79824baaa6 change price ids 2026-07-02 19:19:06 -07:00
4 changed files with 99 additions and 135 deletions
-7
View File
@@ -1,7 +0,0 @@
# Flowy.llink
This project was a radical experiment to transform how teams communicate. The experience revolves around async voice and video clips, with the playback experience being somewhat like Instagram stories that auto-play.
The goal was to replace live Zoom-style meetings, which are draining, and bring relief to teams by making more conversations async, while retaining natural and high-fidelity with pitch, tone, facial expressions.
Due to changing conditions in the environment with regards to AI and data sovereignty (and lack of desire to maintain and market this product), we have decided to open source it. Now you can clone, modify, and host it in your own cloud.
+99
View File
@@ -0,0 +1,99 @@
version: '3'
vars:
DEV_REPO: us-west2-docker.pkg.dev/flowy-dev-440017/deployments
PROD_REPO: us-west2-docker.pkg.dev/flowy-prod-440017/deployments
tasks:
generate:
desc: Generate protobuf code and run go generate
cmds:
- task: genproto
- go generate ./...
format:
desc: Format go files
cmds:
- go fmt ./...
genproto:
desc: Generate Go code from .proto files via docker
vars:
PROTO_DIR: '{{.PROTO_DIR | default "./protocol"}}'
OUT_DIR: '{{.OUT_DIR | default "./genproto"}}'
cmds:
- 'echo "Proto directory: {{.PROTO_DIR}}"'
- 'echo "Output directory: {{.OUT_DIR}}"'
- rm -rf {{.OUT_DIR}}
- mkdir -p {{.OUT_DIR}}
- |
docker run --rm \
-v "{{.PROTO_DIR}}/":/protocol \
-v "{{.OUT_DIR}}":/genproto \
--workdir / \
talksik/golang-protoc:latest \
sh -c 'protoc --proto_path=./protocol \
--go_out=./genproto \
--go_opt=paths=source_relative \
--go-grpc_out=./genproto \
--go-grpc_opt=paths=source_relative \
$(find ./protocol -name "*.proto")'
test:
desc: Run tests with pretty output via gotestfmt
cmds:
- go test -json ./... | docker run -i ghcr.io/gotesttools/gotestfmt:latest
create-migration:
desc: 'Create new migration (usage: task create-migration ARG=create_users_table)'
cmds:
- 'echo "Creating migration with name {{.ARG}}"'
- docker run -v ./migrations:/migrations --network host migrate/migrate create -ext sql -seq -dir /migrations {{.ARG}}
dev-database:
desc: Open psql shell against the dev database
interactive: true
cmds:
- |
kubectl run postgres-client \
--rm -it --image=postgres:latest \
--env="LLINK_POSTGRES_CONNECTION_URL=$(kubectl get secret shared-secrets -o jsonpath='{.data.LLINK_POSTGRES_CONNECTION_URL}' --context dev | base64 --decode)" \
--context dev \
--command -- /bin/bash -c "psql \$LLINK_POSTGRES_CONNECTION_URL"
prod-database:
desc: Open psql shell against the prod database
interactive: true
cmds:
- |
kubectl run postgres-client \
--rm -it --image=postgres:latest \
--env="LLINK_POSTGRES_CONNECTION_URL=$(kubectl get secret shared-secrets -o jsonpath='{.data.LLINK_POSTGRES_CONNECTION_URL}' --context prod | base64 --decode)" \
--context prod \
--command -- /bin/bash -c "psql \$LLINK_POSTGRES_CONNECTION_URL"
migrate-dev:
desc: Run migrations against dev cluster
cmds:
- kubectl delete job migrations --ignore-not-found --context=dev
- SKAFFOLD_DEFAULT_REPO={{.DEV_REPO}} skaffold run -p migrations --kube-context dev --tail
migrate-prod:
desc: Run migrations against prod cluster
cmds:
- kubectl delete job migrations --ignore-not-found --context=prod
- SKAFFOLD_DEFAULT_REPO={{.PROD_REPO}} skaffold run -p migrations --kube-context prod --tail
deploy-dev:
desc: 'Deploy to dev (optionally MODULE=orion to deploy a single service)'
cmds:
- task: generate
- task: test
- SKAFFOLD_DEFAULT_REPO={{.DEV_REPO}} skaffold run -p dev {{if .MODULE}}-m {{.MODULE}}{{end}} --kube-context dev --port-forward --tail
deploy-prod:
desc: 'Deploy to prod (optionally MODULE=orion to deploy a single service)'
cmds:
- task: generate
- task: test
- SKAFFOLD_DEFAULT_REPO={{.PROD_REPO}} skaffold run -p prod {{if .MODULE}}-m {{.MODULE}}{{end}} --kube-context prod --port-forward --tail
-19
View File
@@ -1,19 +0,0 @@
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Per-human membership mirror maintained by Orion's service account.
// Locked from clients so the membership list cannot leak or be mutated.
match /humans/{humanId} {
allow read, write: if false;
}
// Particles: caller must be a current member of the network in the path.
// get() on the mirror is cached across rule evaluations within a single
// request, so this costs 1 billed read per request regardless of query size.
match /networks/{networkId}/children/{particleId=**} {
allow read, write: if request.auth != null
&& networkId in get(/databases/$(database)/documents/humans/$(request.auth.uid)).data.networks;
}
}
}
-109
View File
@@ -1,109 +0,0 @@
resource "google_firebase_project" "default" {
provider = google-beta
project = var.project_id
depends_on = [module.project-services]
}
# Provisions the Firestore database instance.
resource "google_firestore_database" "firestore" {
provider = google-beta
project = google_firebase_project.default.project
name = "(default)"
# See available locations: https://firebase.google.com/docs/firestore/locations
location_id = var.location
# "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules.
type = "FIRESTORE_NATIVE"
concurrency_mode = "OPTIMISTIC"
}
resource "google_firebaserules_ruleset" "default" {
provider = google-beta
project = google_firestore_database.firestore.project
source {
files {
name = "firestore.rules"
# Write security rules in a local file named "firestore.rules".
# Learn more: https://firebase.google.com/docs/firestore/security/get-started
content = file("firestore.rules")
}
}
}
resource "google_firebaserules_release" "firestore" {
provider = google-beta
name = "cloud.firestore"
ruleset_name = google_firebaserules_ruleset.default.name
project = google_firestore_database.firestore.project
}
resource "google_firebase_web_app" "llink" {
provider = google-beta
project = google_firebase_project.default.project
display_name = "Llink app"
}
data "google_firebase_web_app_config" "llink" {
provider = google-beta
project = var.project_id
web_app_id = google_firebase_web_app.llink.app_id
}
// Below indices support the new structure where all subcollections (including network root particles) live under a collection of name "children"
// instead of having `network/n_xxx/particles/p_yyy/children` where the top level subcollection of particles has a distinct name
// Collection index for particles in a single subcollection
resource "google_firestore_index" "list_particles_index" {
project = var.project_id
collection = "children"
query_scope = "COLLECTION"
fields {
field_path = "visible_to"
array_config = "CONTAINS"
}
fields {
field_path = "status"
order = "ASCENDING"
}
fields {
field_path = "last_child_created_at"
order = "DESCENDING"
}
fields {
field_path = "__name__"
order = "DESCENDING"
}
depends_on = [google_firestore_database.firestore]
}
// Collection group index for particles across all subcollections
resource "google_firestore_field" "particle_children_created_at" {
database = google_firestore_database.firestore.name
project = var.project_id
collection = "children"
field = "created_at"
index_config {
indexes {
order = "DESCENDING"
query_scope = "COLLECTION_GROUP"
}
indexes {
order = "ASCENDING"
query_scope = "COLLECTION_GROUP"
}
indexes {
order = "DESCENDING"
query_scope = "COLLECTION"
}
indexes {
order = "ASCENDING"
query_scope = "COLLECTION"
}
}
}