Compare commits
No commits in common. "dde4eb337cbeec08ac489d40ce521f04a532dd26" and "350a6f86d943f2cd2c6f7b5188d8adbbb447279e" have entirely different histories.
dde4eb337c
...
350a6f86d9
41
README.md
41
README.md
@ -421,7 +421,7 @@ The following basic use cases are to be implemented at the first time.
|
|||||||
|
|
||||||
- [X] A user signs up
|
- [X] A user signs up
|
||||||
- [X] A user logs in
|
- [X] A user logs in
|
||||||
- [X] A user lists their events (pagination)
|
- [] A user lists their events (pagination)
|
||||||
- [] A user sees the detail of an event (description, members, amount)
|
- [] A user sees the detail of an event (description, members, amount)
|
||||||
- [] A user sees the expenses of an event (total amount, personal expenses, pagination)
|
- [] A user sees the expenses of an event (total amount, personal expenses, pagination)
|
||||||
- [] A user sees the detail of an expense: (time, amount, payers, recipients)
|
- [] A user sees the detail of an expense: (time, amount, payers, recipients)
|
||||||
@ -430,7 +430,7 @@ The following basic use cases are to be implemented at the first time.
|
|||||||
- [] A user deletes an expense (may handle some extra access control)
|
- [] A user deletes an expense (may handle some extra access control)
|
||||||
- [] A user restore a deleted expense
|
- [] A user restore a deleted expense
|
||||||
- [] A user can pay the debt to other members
|
- [] A user can pay the debt to other members
|
||||||
- [X] A user creates an event (and participate to it)
|
- [X] A user creates an event
|
||||||
- [] A user updates the event info
|
- [] A user updates the event info
|
||||||
- [] A user invites another user by sending a mail with a token.
|
- [] A user invites another user by sending a mail with a token.
|
||||||
- [] A user joins an event by accepting an invitation
|
- [] A user joins an event by accepting an invitation
|
||||||
@ -449,40 +449,3 @@ work on other aspects. For example:
|
|||||||
- ex. Trip journal...
|
- ex. Trip journal...
|
||||||
|
|
||||||
Stop dreaming... Just do the simple stuff first!
|
Stop dreaming... Just do the simple stuff first!
|
||||||
|
|
||||||
### 2024/10/18
|
|
||||||
|
|
||||||
I spent some time to figure out this one! But I don't actually need it for now.
|
|
||||||
So I just keep it here:
|
|
||||||
|
|
||||||
```SQL
|
|
||||||
SELECT
|
|
||||||
e.id,
|
|
||||||
e.name,
|
|
||||||
e.description,
|
|
||||||
e.created_at,
|
|
||||||
json_build_object(
|
|
||||||
'id', o.id,
|
|
||||||
'first_name', o.first_name,
|
|
||||||
'last_name', o.last_name
|
|
||||||
) AS owner,
|
|
||||||
json_agg(
|
|
||||||
json_build_object(
|
|
||||||
'id', u.id,
|
|
||||||
'first_name', u.first_name,
|
|
||||||
'last_name', u.last_name
|
|
||||||
)
|
|
||||||
) AS users -- Aggregation for users in the event
|
|
||||||
FROM "event" e
|
|
||||||
JOIN "participation" p ON p.event_id = e.id -- participation linked with the event
|
|
||||||
JOIN "user" u ON u.id = p.user_id -- and the query user
|
|
||||||
JOIN "user" o ON o.id = e.owner_id -- get the owner info
|
|
||||||
WHERE e.id IN (
|
|
||||||
SELECT pt.event_id FROM participation pt WHERE pt.user_id = $1
|
|
||||||
-- consider the events participated by user_id
|
|
||||||
)
|
|
||||||
GROUP BY
|
|
||||||
e.id, e.name, e.description, e.created_at,
|
|
||||||
o.id, o.first_name, o.last_name;
|
|
||||||
|
|
||||||
```
|
|
||||||
|
@ -85,14 +85,6 @@ func TestSessionCreate(t *testing.T) {
|
|||||||
Email: "unregistered@error.com",
|
Email: "unregistered@error.com",
|
||||||
Password: "strong password",
|
Password: "strong password",
|
||||||
}, usecase.UserNotExist},
|
}, usecase.UserNotExist},
|
||||||
{"wrong email", createParams{
|
|
||||||
Email: "error.com",
|
|
||||||
Password: "strong password",
|
|
||||||
}, UserParamsErr},
|
|
||||||
{"no passwrd", createParams{
|
|
||||||
Email: "no@error.com",
|
|
||||||
Password: "",
|
|
||||||
}, UserParamsErr},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token.Init("secret", 1*time.Second)
|
token.Init("secret", 1*time.Second)
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
-- name: InsertEvent :one
|
|
||||||
INSERT INTO "event" (
|
|
||||||
name, description, total_amount, default_currency, owner_id, created_at, updated_at
|
|
||||||
) VALUES ( $1, $2, $3, $4, $5, $6, $7 )
|
|
||||||
RETURNING *;
|
|
||||||
|
|
||||||
-- name: ListEventsByUserID :many
|
|
||||||
SELECT
|
|
||||||
e.id,
|
|
||||||
e.name,
|
|
||||||
e.description,
|
|
||||||
e.created_at,
|
|
||||||
json_build_object(
|
|
||||||
'id', o.id,
|
|
||||||
'first_name', o.first_name,
|
|
||||||
'last_name', o.last_name
|
|
||||||
) AS owner
|
|
||||||
FROM "event" e
|
|
||||||
JOIN "participation" p ON p.event_id = e.id -- participation linked with the event
|
|
||||||
JOIN "user" o ON o.id = e.owner_id -- get the owner info
|
|
||||||
WHERE e.id IN (
|
|
||||||
SELECT pt.event_id FROM participation pt WHERE pt.user_id = $1 -- consider the events participated by user_id
|
|
||||||
)
|
|
||||||
GROUP BY
|
|
||||||
e.id, e.name, e.description, e.created_at,
|
|
||||||
o.id, o.first_name, o.last_name;
|
|
||||||
|
|
||||||
-- name: GetEventByID :one
|
|
||||||
SELECT
|
|
||||||
e.id,
|
|
||||||
e.name,
|
|
||||||
e.description,
|
|
||||||
e.total_amount,
|
|
||||||
e.default_currency,
|
|
||||||
e.created_at,
|
|
||||||
e.updated_at,
|
|
||||||
json_build_object(
|
|
||||||
'id', o.id,
|
|
||||||
'first_name', o.first_name,
|
|
||||||
'last_name', o.last_name
|
|
||||||
) AS owner,
|
|
||||||
json_agg(
|
|
||||||
json_build_object(
|
|
||||||
'id', u.id,
|
|
||||||
'first_name', u.first_name,
|
|
||||||
'last_name', u.last_name
|
|
||||||
)
|
|
||||||
) AS users -- Aggregation for users in the event
|
|
||||||
FROM "event" e
|
|
||||||
JOIN "participation" p ON p.event_id = e.id -- participation linked with the event
|
|
||||||
JOIN "user" u ON u.id = p.user_id -- and the query user
|
|
||||||
JOIN "user" o ON o.id = e.owner_id -- get the owner info
|
|
||||||
WHERE e.id = $1
|
|
||||||
GROUP BY
|
|
||||||
e.id, e.name, e.description, e.created_at, e.updated_at,
|
|
||||||
e.total_amount, e.default_currency,
|
|
||||||
o.id, o.first_name, o.last_name;
|
|
||||||
|
|
@ -1,174 +0,0 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// sqlc v1.27.0
|
|
||||||
// source: event.sql
|
|
||||||
|
|
||||||
package sqlc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const getEventByID = `-- name: GetEventByID :one
|
|
||||||
SELECT
|
|
||||||
e.id,
|
|
||||||
e.name,
|
|
||||||
e.description,
|
|
||||||
e.total_amount,
|
|
||||||
e.default_currency,
|
|
||||||
e.created_at,
|
|
||||||
e.updated_at,
|
|
||||||
json_build_object(
|
|
||||||
'id', o.id,
|
|
||||||
'first_name', o.first_name,
|
|
||||||
'last_name', o.last_name
|
|
||||||
) AS owner,
|
|
||||||
json_agg(
|
|
||||||
json_build_object(
|
|
||||||
'id', u.id,
|
|
||||||
'first_name', u.first_name,
|
|
||||||
'last_name', u.last_name
|
|
||||||
)
|
|
||||||
) AS users -- Aggregation for users in the event
|
|
||||||
FROM "event" e
|
|
||||||
JOIN "participation" p ON p.event_id = e.id -- participation linked with the event
|
|
||||||
JOIN "user" u ON u.id = p.user_id -- and the query user
|
|
||||||
JOIN "user" o ON o.id = e.owner_id -- get the owner info
|
|
||||||
WHERE e.id = $1
|
|
||||||
GROUP BY
|
|
||||||
e.id, e.name, e.description, e.created_at, e.updated_at,
|
|
||||||
e.total_amount, e.default_currency,
|
|
||||||
o.id, o.first_name, o.last_name
|
|
||||||
`
|
|
||||||
|
|
||||||
type GetEventByIDRow struct {
|
|
||||||
ID int32
|
|
||||||
Name string
|
|
||||||
Description sql.NullString
|
|
||||||
TotalAmount sql.NullInt32
|
|
||||||
DefaultCurrency string
|
|
||||||
CreatedAt time.Time
|
|
||||||
UpdatedAt time.Time
|
|
||||||
Owner json.RawMessage
|
|
||||||
Users json.RawMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetEventByID(ctx context.Context, id int32) (GetEventByIDRow, error) {
|
|
||||||
row := q.db.QueryRowContext(ctx, getEventByID, id)
|
|
||||||
var i GetEventByIDRow
|
|
||||||
err := row.Scan(
|
|
||||||
&i.ID,
|
|
||||||
&i.Name,
|
|
||||||
&i.Description,
|
|
||||||
&i.TotalAmount,
|
|
||||||
&i.DefaultCurrency,
|
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
&i.Owner,
|
|
||||||
&i.Users,
|
|
||||||
)
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
const insertEvent = `-- name: InsertEvent :one
|
|
||||||
INSERT INTO "event" (
|
|
||||||
name, description, total_amount, default_currency, owner_id, created_at, updated_at
|
|
||||||
) VALUES ( $1, $2, $3, $4, $5, $6, $7 )
|
|
||||||
RETURNING id, name, description, default_currency, owner_id, created_at, updated_at, total_amount
|
|
||||||
`
|
|
||||||
|
|
||||||
type InsertEventParams struct {
|
|
||||||
Name string
|
|
||||||
Description sql.NullString
|
|
||||||
TotalAmount sql.NullInt32
|
|
||||||
DefaultCurrency string
|
|
||||||
OwnerID int32
|
|
||||||
CreatedAt time.Time
|
|
||||||
UpdatedAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) (Event, error) {
|
|
||||||
row := q.db.QueryRowContext(ctx, insertEvent,
|
|
||||||
arg.Name,
|
|
||||||
arg.Description,
|
|
||||||
arg.TotalAmount,
|
|
||||||
arg.DefaultCurrency,
|
|
||||||
arg.OwnerID,
|
|
||||||
arg.CreatedAt,
|
|
||||||
arg.UpdatedAt,
|
|
||||||
)
|
|
||||||
var i Event
|
|
||||||
err := row.Scan(
|
|
||||||
&i.ID,
|
|
||||||
&i.Name,
|
|
||||||
&i.Description,
|
|
||||||
&i.DefaultCurrency,
|
|
||||||
&i.OwnerID,
|
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
&i.TotalAmount,
|
|
||||||
)
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
const listEventsByUserID = `-- name: ListEventsByUserID :many
|
|
||||||
SELECT
|
|
||||||
e.id,
|
|
||||||
e.name,
|
|
||||||
e.description,
|
|
||||||
e.created_at,
|
|
||||||
json_build_object(
|
|
||||||
'id', o.id,
|
|
||||||
'first_name', o.first_name,
|
|
||||||
'last_name', o.last_name
|
|
||||||
) AS owner
|
|
||||||
FROM "event" e
|
|
||||||
JOIN "participation" p ON p.event_id = e.id -- participation linked with the event
|
|
||||||
JOIN "user" o ON o.id = e.owner_id -- get the owner info
|
|
||||||
WHERE e.id IN (
|
|
||||||
SELECT pt.event_id FROM participation pt WHERE pt.user_id = $1 -- consider the events participated by user_id
|
|
||||||
)
|
|
||||||
GROUP BY
|
|
||||||
e.id, e.name, e.description, e.created_at,
|
|
||||||
o.id, o.first_name, o.last_name
|
|
||||||
`
|
|
||||||
|
|
||||||
type ListEventsByUserIDRow struct {
|
|
||||||
ID int32
|
|
||||||
Name string
|
|
||||||
Description sql.NullString
|
|
||||||
CreatedAt time.Time
|
|
||||||
Owner json.RawMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) ListEventsByUserID(ctx context.Context, userID int32) ([]ListEventsByUserIDRow, error) {
|
|
||||||
rows, err := q.db.QueryContext(ctx, listEventsByUserID, userID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
var items []ListEventsByUserIDRow
|
|
||||||
for rows.Next() {
|
|
||||||
var i ListEventsByUserIDRow
|
|
||||||
if err := rows.Scan(
|
|
||||||
&i.ID,
|
|
||||||
&i.Name,
|
|
||||||
&i.Description,
|
|
||||||
&i.CreatedAt,
|
|
||||||
&i.Owner,
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
items = append(items, i)
|
|
||||||
}
|
|
||||||
if err := rows.Close(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := rows.Err(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return items, nil
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
-- name: InsertParticipation :one
|
|
||||||
INSERT INTO participation (
|
|
||||||
user_id, event_id, invited_by_user_id, created_at, updated_at
|
|
||||||
) VALUES ($1, $2, $3, $4, $5)
|
|
||||||
RETURNING *;
|
|
@ -1,47 +0,0 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// sqlc v1.27.0
|
|
||||||
// source: participation.sql
|
|
||||||
|
|
||||||
package sqlc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const insertParticipation = `-- name: InsertParticipation :one
|
|
||||||
INSERT INTO participation (
|
|
||||||
user_id, event_id, invited_by_user_id, created_at, updated_at
|
|
||||||
) VALUES ($1, $2, $3, $4, $5)
|
|
||||||
RETURNING id, user_id, event_id, invited_by_user_id, created_at, updated_at
|
|
||||||
`
|
|
||||||
|
|
||||||
type InsertParticipationParams struct {
|
|
||||||
UserID int32
|
|
||||||
EventID int32
|
|
||||||
InvitedByUserID sql.NullInt32
|
|
||||||
CreatedAt time.Time
|
|
||||||
UpdatedAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) InsertParticipation(ctx context.Context, arg InsertParticipationParams) (Participation, error) {
|
|
||||||
row := q.db.QueryRowContext(ctx, insertParticipation,
|
|
||||||
arg.UserID,
|
|
||||||
arg.EventID,
|
|
||||||
arg.InvitedByUserID,
|
|
||||||
arg.CreatedAt,
|
|
||||||
arg.UpdatedAt,
|
|
||||||
)
|
|
||||||
var i Participation
|
|
||||||
err := row.Scan(
|
|
||||||
&i.ID,
|
|
||||||
&i.UserID,
|
|
||||||
&i.EventID,
|
|
||||||
&i.InvitedByUserID,
|
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
)
|
|
||||||
return i, err
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
DROP TABLE "event"
|
|
@ -1,10 +0,0 @@
|
|||||||
CREATE TABLE "event" (
|
|
||||||
"id" serial NOT NULL,
|
|
||||||
PRIMARY KEY ("id"),
|
|
||||||
"name" character varying(255) NOT NULL,
|
|
||||||
"description" character varying(10000) NULL,
|
|
||||||
"default_currency" character varying(255) NOT NULL,
|
|
||||||
"owner_id" integer NOT NULL,
|
|
||||||
"created_at" date NOT NULL,
|
|
||||||
"updated_at" date NOT NULL
|
|
||||||
);
|
|
@ -1 +0,0 @@
|
|||||||
DROP TABLE participation;
|
|
@ -1,16 +0,0 @@
|
|||||||
CREATE TABLE "participation" (
|
|
||||||
"id" serial NOT NULL,
|
|
||||||
PRIMARY KEY ("id"),
|
|
||||||
"user_id" integer NOT NULL,
|
|
||||||
"event_id" integer NOT NULL,
|
|
||||||
"invited_by_user_id" integer NULL,
|
|
||||||
"created_at" date NOT NULL,
|
|
||||||
"updated_at" date NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE "participation"
|
|
||||||
ADD FOREIGN KEY ("event_id") REFERENCES "event" ("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
ALTER TABLE "participation"
|
|
||||||
ADD FOREIGN KEY ("user_id") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
ALTER TABLE "event"
|
|
||||||
ADD "total_amount" integer NULL;
|
|
@ -1,2 +0,0 @@
|
|||||||
ALTER TABLE "participation"
|
|
||||||
ADD CONSTRAINT unique_user_event UNIQUE ("user_id", "event_id");
|
|
Loading…
x
Reference in New Issue
Block a user