Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: plutov/formulosity
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.1.5
Choose a base ref
...
head repository: plutov/formulosity
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref

Commits on Sep 30, 2024

  1. Copy the full SHA
    bd33ae2 View commit details

Commits on Oct 2, 2024

  1. Feat/file type

    jacksonwun committed Oct 2, 2024
    Copy the full SHA
    32d675d View commit details

Commits on Oct 3, 2024

  1. feat/file_type

    taobob629 committed Oct 3, 2024
    Copy the full SHA
    70934e5 View commit details

Commits on Oct 4, 2024

  1. Copy the full SHA
    3538607 View commit details

Commits on Oct 5, 2024

  1. Merge pull request #27 from jacksonwun/master

    Feat/file type
    plutov authored Oct 5, 2024
    Copy the full SHA
    7a2b162 View commit details

Commits on Oct 6, 2024

  1. resolving conflicts

    krishnateja262 committed Oct 6, 2024
    Copy the full SHA
    886872d View commit details
  2. resolving conflicts

    krishnateja262 committed Oct 6, 2024
    Copy the full SHA
    c10c19c View commit details

Commits on Oct 12, 2024

  1. Copy the full SHA
    c90f2a8 View commit details
  2. Copy the full SHA
    ca6cc5d View commit details
  3. adding log

    krishnateja262 committed Oct 12, 2024
    Copy the full SHA
    215cd5d View commit details
  4. Copy the full SHA
    fc83ae8 View commit details

Commits on Oct 13, 2024

  1. Copy the full SHA
    a9e9c34 View commit details
  2. Copy the full SHA
    ee2122c View commit details

Commits on Oct 16, 2024

  1. Merge pull request #25 from krishnateja262/feature/webhooks

    first draft with webhook support
    plutov authored Oct 16, 2024
    Copy the full SHA
    b84276e View commit details
  2. remove unused start.sh

    plutov committed Oct 16, 2024
    Copy the full SHA
    914c248 View commit details
  3. Bump next from 14.1.1 to 14.2.15 in /ui

    Bumps [next](https://github.com/vercel/next.js) from 14.1.1 to 14.2.15.
    - [Release notes](https://github.com/vercel/next.js/releases)
    - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
    - [Commits](vercel/next.js@v14.1.1...v14.2.15)
    
    ---
    updated-dependencies:
    - dependency-name: next
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Oct 16, 2024
    Copy the full SHA
    dc024dd View commit details
  4. Merge pull request #31 from plutov/dependabot/npm_and_yarn/ui/next-14…

    ….2.15
    
    Bump next from 14.1.1 to 14.2.15 in /ui
    plutov authored Oct 16, 2024
    Copy the full SHA
    bbc34a9 View commit details

Commits on Oct 17, 2024

  1. Copy the full SHA
    2d8deb6 View commit details

Commits on Oct 18, 2024

  1. resolving conflicts

    krishnateja262 committed Oct 18, 2024
    Copy the full SHA
    6a41144 View commit details
  2. Merge pull request #34 from krishnateja262/feature/download-file

    adding download button
    plutov authored Oct 18, 2024
    Copy the full SHA
    fd04b0d View commit details
  3. Add github actions and linter

    plutov committed Oct 18, 2024
    Copy the full SHA
    13ebc20 View commit details

Commits on Oct 21, 2024

  1. Copy the full SHA
    f8f9454 View commit details

Commits on Oct 28, 2024

  1. Copy the full SHA
    c189bc5 View commit details

Commits on Nov 1, 2024

  1. Merge pull request #36 from unamdev0/main

    added AIR for live reloading go when changes are made
    plutov authored Nov 1, 2024
    Copy the full SHA
    58b1d68 View commit details

Commits on Feb 13, 2025

  1. #38: use slog

    Signed-off-by: plutov <a.pliutau@gmail.com>
    plutov committed Feb 13, 2025
    Copy the full SHA
    9d72b9c View commit details
  2. #38: use slog, go mod update

    Signed-off-by: plutov <a.pliutau@gmail.com>
    plutov committed Feb 13, 2025
    Copy the full SHA
    140746e View commit details

Commits on Mar 8, 2025

  1. postgres default

    Signed-off-by: plutov <a.pliutau@gmail.com>
    plutov committed Mar 8, 2025
    Copy the full SHA
    589178f View commit details

Commits on Mar 16, 2025

  1. cleanup

    Signed-off-by: plutov <a.pliutau@gmail.com>
    plutov committed Mar 16, 2025
    Copy the full SHA
    efe4539 View commit details
Showing with 1,165 additions and 1,273 deletions.
  1. +0 −19 .github/workflows/fly-deploy.yml
  2. +49 −3 .github/workflows/test.yaml
  3. +2 −0 .gitignore
  4. +1 −1 LICENSE
  5. +22 −24 README.md
  6. +2 −2 api/Dockerfile
  7. +1 −0 api/Makefile
  8. +7 −12 api/cmd/{console-api → api}/api.go
  9. +0 −15 api/fly.toml
  10. +12 −10 api/go.mod
  11. +34 −30 api/go.sum
  12. 0 api/migrations/postgres/000001_schema.down.sql
  13. +48 −43 api/migrations/postgres/000001_schema.up.sql
  14. 0 api/migrations/sqlite/000001_schema.down.sql
  15. +39 −30 api/migrations/sqlite/000001_schema.up.sql
  16. +69 −487 api/mocks/interface.go
  17. +8 −7 api/pkg/controllers/router.go
  18. +66 −1 api/pkg/controllers/survey_sessions.go
  19. +1 −2 api/pkg/controllers/surveys.go
  20. +0 −188 api/pkg/log/entry.go
  21. +0 −243 api/pkg/log/log.go
  22. +8 −3 api/pkg/parser/parser.go
  23. +7 −1 api/pkg/parser/parser_test.go
  24. +3 −4 api/pkg/parser/survey.go
  25. +12 −2 api/pkg/services/services.go
  26. +89 −0 api/pkg/storage/file.go
  27. +91 −0 api/pkg/storage/file_test.go
  28. +9 −0 api/pkg/storage/interface.go
  29. +17 −2 api/pkg/storage/postgres.go
  30. +29 −4 api/pkg/storage/sqlite.go
  31. +29 −10 api/pkg/surveys/answers.go
  32. +10 −11 api/pkg/surveys/manage.go
  33. +2 −3 api/pkg/surveys/persist.go
  34. +51 −13 api/pkg/surveys/sessions.go
  35. +11 −10 api/pkg/surveys/sync.go
  36. +64 −0 api/pkg/types/answers.go
  37. +62 −0 api/pkg/types/answers_test.go
  38. +10 −0 api/pkg/types/files.go
  39. +59 −3 api/pkg/types/questions.go
  40. +14 −5 api/pkg/types/survey.go
  41. +6 −0 api/pkg/types/survey_session.go
  42. +33 −0 api/pkg/types/webhook.go
  43. +7 −0 api/surveys/custom_theme/questions.yaml
  44. +3 −0 api/surveys/short/metadata.yaml
  45. +16 −23 compose.yaml
  46. +0 −3 start.sh
  47. +63 −48 ui/package-lock.json
  48. +2 −1 ui/package.json
  49. +23 −3 ui/src/components/app/SurveyResponsesPage.tsx
  50. +26 −1 ui/src/components/app/survey/SurveyQuestions.tsx
  51. +41 −6 ui/src/lib/api.ts
  52. +7 −0 ui/src/lib/types.ts
19 changes: 0 additions & 19 deletions .github/workflows/fly-deploy.yml

This file was deleted.

52 changes: 49 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,64 @@
name: Tests
on: [push]
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
name: Lint Go
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: 1.23

- name: Check out code
uses: actions/checkout@v4

- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.60
working-directory: ./api

test:
name: Tests
name: Test Go
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: 1.23

- name: Check out code into the Go module directory
- name: Check out code
uses: actions/checkout@v4

- name: Run Tests
working-directory: ./api
run: go test -v -bench=. -race ./...

lint-ui:
name: Lint UI
runs-on: ubuntu-latest
strategy:
matrix:
node_version: [20]

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v4
with:
node_version: ${{ matrix.node_version }}

- name: run CI
working-directory: ./ui
run: |
npm install
npm run lint
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ api/pkg/github/tmp/
api/pkg/parser/tmp/
api/postgres-data/
api/sqlite3/
api/uploads/
ui/node_modules
ui/.next/
ui/out/
@@ -11,3 +12,4 @@ ui/yarn-debug.log*
ui/yarn-error.log*
.DS_Store
.env
tmp/
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Alex Pliutau
Copyright (c) 2025 Alex Pliutau

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
46 changes: 22 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
<p align="center" width="100%">
<img src="https://github.com/plutov/formulosity/blob/main/ui/public/logo_wide.png" height="100px">
</p>
<img src="https://github.com/plutov/formulosity/blob/main/ui/public/logo_wide.png" height="100px">

<p align="center">
Formulosity is a self-hosted app for building and deploying the surveys using code instead of traditional survey builders.
</p>
## Formulosity - self-hosted Surveys as Code platform.

This approach offers a number of advantages, including:

@@ -14,13 +10,11 @@ This approach offers a number of advantages, including:

**Formulosity** uses human-readable declarative language [YAML](https://en.wikipedia.org/wiki/YAML).

<p align="center" width="100%">
<img src="https://github.com/plutov/formulosity/blob/main/ui/public/questions.png" height="250px">
</p>
<img src="https://github.com/plutov/formulosity/blob/main/ui/public/questions.png" height="250px">

## Features

- [x] Management API
- [x] API first
- [x] Survey UI: for end users (respondents)
- [x] Console UI: manage surveys
- [x] YAML survey configuration
@@ -33,19 +27,10 @@ This approach offers a number of advantages, including:
- [x] Different database options: SQLite and Postgres
- [x] Continue where you left off
- [x] Advanced validation rules
- [x] Detect survey changes in real time
- [x] Export responses in UI or via API
- [ ] Advanced question types
- [ ] Pipe answers into the following questions

## See it in Action!

<p align="center" width="100%">
<a href="https://formulosity.vercel.app/app">Admin Panel</a>
</p>

Note: use `user` / `pass` to login into the Console UI.

## Survey Structure

Each directory in `SURVEYS_DIR` is a survey. You can configure the source of your surveys by setting different `SURVEYS_DIR` env var.
@@ -64,7 +49,7 @@ surveys/
└── ...
```

To get started, check out the `./surveys` folder with multiple examples.
To get started, check out the `./api/surveys` folder with multiple examples.

## Survey Files

@@ -253,11 +238,26 @@ Presents a question where users can only answer "yes" or "no".
### Email

Prompts user to enter their email

```yaml
- type: email
label: Please enter your email.
```

### File

Prompts user to upload their file based on a given formats and maximum upload size.

```yaml
- type: file
label: Upload a Berlin Image
validation:
formats:
- .jpg
- .png
max_size_bytes: 5*1024*1024 # 5 MB
```

## Responses

Responses can be shown in the UI and exported as a JSON. Alternatively you can use REST API to get survey resposnes:
@@ -282,24 +282,22 @@ Where `{SURVEY_ID}` id the UUID of a given survey.
docker-compose up -d --build
```
And you should be able to access the UI on http://localhost:3000 (default basic auth: `user:pass`).
And you should be able to access the UI on [localhost:3000](http://localhost:3000) (default basic auth: `user:pass`).
You can deploy individual services to any cloud provider or self host them.
- Go backend. It's packaged as a Docker container and can be deployed anywhere.
- Next.js frontend. It's also packaged as a Docker container, but also can be deployed to Vercel for example.
- [Optional] Postgres database. You can use managed Postgres services or deploy it yourself.
The demo service (links above) is deployed to Fly.io (Go, SQLite) and Vercel (Next.js) and are under the free tiers.
### Environment Variables
API:
- `DATABASE_TYPE` - `sqlite` or `postgres`
- `DATABASE_URL` - Postgres or SQLite connection string
- `LOG_LEVEL` - Log level, e.g. `info`
- `SURVEYS_DIR` - Directory with surveys, e.g. `/root/surveys`. It's suggested to use mounted volume for this directory.
- `UPLOADS_DIR` - Directory for uploading files from the survey forms.
UI:
4 changes: 2 additions & 2 deletions api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.23-alpine AS builder
FROM golang:1.24-alpine AS builder

RUN apk add build-base

@@ -13,7 +13,7 @@ COPY ./cmd ./cmd
COPY ./pkg ./pkg
COPY ./migrations ./migrations
COPY ./surveys ./surveys-examples
RUN CGO_ENABLED=1 GOOS=linux go build -o api -tags enablecgo cmd/console-api/api.go
RUN CGO_ENABLED=1 GOOS=linux go build -o api -tags enablecgo cmd/api/api.go

FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata bash
1 change: 1 addition & 0 deletions api/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

lint:
golangci-lint run

19 changes: 7 additions & 12 deletions api/cmd/console-api/api.go → api/cmd/api/api.go
Original file line number Diff line number Diff line change
@@ -4,36 +4,31 @@ import (
"os"

controllers "github.com/plutov/formulosity/api/pkg/controllers"
"github.com/plutov/formulosity/api/pkg/log"
"github.com/plutov/formulosity/api/pkg/services"
"github.com/plutov/formulosity/api/pkg/surveys"
)

func main() {
log.Named("console-api")
logLevel := "info"
if os.Getenv("LOG_LEVEL") != "" {
logLevel = os.Getenv("LOG_LEVEL")
}
log.SetLogLevel(logLevel)

svc, err := services.InitServices()
if err != nil {
log.WithError(err).Fatal("unable to init dependencies")
svc.Logger.Error("unable to init dependencies", "err", err)
os.Exit(1)
}

if err := surveys.SyncSurveys(svc); err != nil {
log.WithError(err).Fatal("unable to sync surveys")
svc.Logger.Error("unable to sync surveys", "err", err)
os.Exit(1)
}

handler := controllers.NewHandler(svc)
if err != nil {
log.WithError(err).Fatal("unable to start server")
svc.Logger.Error("unable to start server", "err", err)
os.Exit(1)
}

r := controllers.NewRouter(handler)

if err := r.Start(":8080"); err != nil {
log.WithError(err).Fatal("shutting down the server")
svc.Logger.Info("shutting down the server", "err", err)
}
}
15 changes: 0 additions & 15 deletions api/fly.toml

This file was deleted.

22 changes: 12 additions & 10 deletions api/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/plutov/formulosity/api

go 1.23
go 1.24

require (
github.com/fsnotify/fsnotify v1.7.0
@@ -11,8 +11,7 @@ require (
github.com/matoous/go-nanoid/v2 v2.0.0
github.com/mattn/go-sqlite3 v1.14.22
github.com/microcosm-cc/bluemonday v1.0.27
github.com/stretchr/testify v1.8.4
go.uber.org/zap v1.26.0
github.com/stretchr/testify v1.9.0
gopkg.in/yaml.v3 v3.0.1
)

@@ -24,19 +23,22 @@ require (
github.com/gorilla/css v1.0.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.25.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)
Loading