@@ -0,0 +1,12 @@ | |||||
[package] | |||||
name = "puffpastry-backend" | |||||
version = "0.1.0" | |||||
edition = "2021" | |||||
[dependencies] | |||||
actix-web = { version = "4", features = ["cookies"] } | |||||
serde = { version = "1.0", features = ["derive"] } | |||||
diesel = { version = "2.2.0", features = ["postgres", "chrono"] } | |||||
dotenvy = "0.15" | |||||
chrono = { version = "0.4.38", features = ["serde"] } | |||||
uuid = { version = "1.10.0", features = ["v4"] } |
@@ -0,0 +1,9 @@ | |||||
# For documentation on how to configure this file, | |||||
# see https://diesel.rs/guides/configuring-diesel-cli | |||||
[print_schema] | |||||
file = "src/schema.rs" | |||||
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"] | |||||
[migrations_directory] | |||||
dir = "/home/jbell/RustroverProjects/puffpastry-backend/migrations" |
@@ -0,0 +1,6 @@ | |||||
-- This file was automatically created by Diesel to setup helper functions | |||||
-- and other internal bookkeeping. This file is safe to edit, any future | |||||
-- changes will be added to existing projects as new migrations. | |||||
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); | |||||
DROP FUNCTION IF EXISTS diesel_set_updated_at(); |
@@ -0,0 +1,36 @@ | |||||
-- This file was automatically created by Diesel to setup helper functions | |||||
-- and other internal bookkeeping. This file is safe to edit, any future | |||||
-- changes will be added to existing projects as new migrations. | |||||
-- Sets up a trigger for the given table to automatically set a column called | |||||
-- `updated_at` whenever the row is modified (unless `updated_at` was included | |||||
-- in the modified columns) | |||||
-- | |||||
-- # Example | |||||
-- | |||||
-- ```sql | |||||
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); | |||||
-- | |||||
-- SELECT diesel_manage_updated_at('users'); | |||||
-- ``` | |||||
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ | |||||
BEGIN | |||||
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s | |||||
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); | |||||
END; | |||||
$$ LANGUAGE plpgsql; | |||||
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ | |||||
BEGIN | |||||
IF ( | |||||
NEW IS DISTINCT FROM OLD AND | |||||
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at | |||||
) THEN | |||||
NEW.updated_at := current_timestamp; | |||||
END IF; | |||||
RETURN NEW; | |||||
END; | |||||
$$ LANGUAGE plpgsql; |
@@ -0,0 +1,2 @@ | |||||
-- This file should undo anything in `up.sql` | |||||
drop table issues; |
@@ -0,0 +1,8 @@ | |||||
-- Your SQL goes here | |||||
create table issues ( | |||||
id serial primary key, | |||||
title text not null, | |||||
paragraph_count smallint, | |||||
telegram_handle text not null, | |||||
created_at timestamp | |||||
); |
@@ -0,0 +1,2 @@ | |||||
-- This file should undo anything in `up.sql` | |||||
drop table sessions; |
@@ -0,0 +1,11 @@ | |||||
-- Your SQL goes here | |||||
create table sessions ( | |||||
id bigserial primary key, | |||||
session_id text not null, | |||||
user_id bigint not null, | |||||
auth_date bigint, | |||||
username text, | |||||
first_name text, | |||||
last_name text, | |||||
photo_url text | |||||
) |
@@ -0,0 +1,2 @@ | |||||
-- This file should undo anything in `up.sql` | |||||
drop table paragraphs; |
@@ -0,0 +1,7 @@ | |||||
-- Your SQL goes here | |||||
create table paragraphs ( | |||||
id bigserial primary key, | |||||
content text not null, | |||||
index int not null, | |||||
post_id int not null references issues(id) | |||||
); |
@@ -0,0 +1,2 @@ | |||||
-- This file should undo anything in `up.sql` | |||||
drop table issue_votes; |
@@ -0,0 +1,8 @@ | |||||
-- Your SQL goes here | |||||
create table issue_votes ( | |||||
id bigserial primary key, | |||||
positive boolean, | |||||
issue_id int not null references issues (id), | |||||
user_id bigint not null, | |||||
unique (issue_id, user_id) | |||||
); |
@@ -0,0 +1,3 @@ | |||||
-- This file should undo anything in `up.sql` | |||||
drop table comment_votes; | |||||
drop table comments; |
@@ -0,0 +1,17 @@ | |||||
-- Your SQL goes here | |||||
create table comments ( | |||||
id bigserial primary key, | |||||
content text not null, | |||||
parent bigint references comments (id) on delete cascade, | |||||
telegram_handle text not null, | |||||
issue_id int not null references issues (id), | |||||
created_at timestamp | |||||
); | |||||
create table comment_votes ( | |||||
id bigserial primary key, | |||||
positive boolean, | |||||
comment_id bigint not null references comments(id), | |||||
user_id bigint not null, | |||||
unique (comment_id, user_id) | |||||
) |
@@ -0,0 +1,33 @@ | |||||
pub mod db; | |||||
pub mod models; | |||||
pub mod schema; | |||||
pub mod repositories; | |||||
pub mod api; | |||||
use actix_web::{web, App, HttpServer, Responder}; | |||||
use api::{issue, session}; | |||||
use crate::api::comment; | |||||
#[actix_web::main] | |||||
async fn main() -> std::io::Result<()> { | |||||
HttpServer::new(|| { | |||||
App::new() | |||||
.service( | |||||
web::scope("/issues") | |||||
.route("/create", web::post().to(issue::add_issue)) | |||||
.route("/list", web::get().to(issue::list_issues)) | |||||
.route("/paragraphs", web::get().to(issue::get_paragraphs)) | |||||
.route("/vote", web::post().to(issue::vote_issue)) | |||||
.route("/get_vote", web::get().to(issue::get_user_vote)) | |||||
.route("/comments", web::get().to(comment::get_comments)) | |||||
) | |||||
.service( | |||||
web::scope("/sessions") | |||||
.route("/authenticate", web::post().to(session::authenticate)) | |||||
.route("/get_username", web::get().to(session::get_username)) | |||||
) | |||||
}) | |||||
.bind(("127.0.0.1", 8080))? | |||||
.run() | |||||
.await | |||||
} |
@@ -0,0 +1,76 @@ | |||||
// @generated automatically by Diesel CLI. | |||||
diesel::table! { | |||||
comment_votes (id) { | |||||
id -> Int8, | |||||
positive -> Nullable<Bool>, | |||||
comment_id -> Int8, | |||||
user_id -> Int8, | |||||
} | |||||
} | |||||
diesel::table! { | |||||
comments (id) { | |||||
id -> Int8, | |||||
content -> Text, | |||||
parent -> Nullable<Int8>, | |||||
telegram_handle -> Text, | |||||
issue_id -> Int4, | |||||
created_at -> Nullable<Timestamp>, | |||||
} | |||||
} | |||||
diesel::table! { | |||||
issue_votes (id) { | |||||
id -> Int8, | |||||
positive -> Nullable<Bool>, | |||||
issue_id -> Int4, | |||||
user_id -> Int8, | |||||
} | |||||
} | |||||
diesel::table! { | |||||
issues (id) { | |||||
id -> Int4, | |||||
title -> Text, | |||||
paragraph_count -> Nullable<Int2>, | |||||
telegram_handle -> Text, | |||||
created_at -> Nullable<Timestamp>, | |||||
} | |||||
} | |||||
diesel::table! { | |||||
paragraphs (id) { | |||||
id -> Int8, | |||||
content -> Text, | |||||
index -> Int4, | |||||
post_id -> Int4, | |||||
} | |||||
} | |||||
diesel::table! { | |||||
sessions (id) { | |||||
id -> Int8, | |||||
session_id -> Text, | |||||
user_id -> Int8, | |||||
auth_date -> Nullable<Int8>, | |||||
username -> Nullable<Text>, | |||||
first_name -> Nullable<Text>, | |||||
last_name -> Nullable<Text>, | |||||
photo_url -> Nullable<Text>, | |||||
} | |||||
} | |||||
diesel::joinable!(comment_votes -> comments (comment_id)); | |||||
diesel::joinable!(comments -> issues (issue_id)); | |||||
diesel::joinable!(issue_votes -> issues (issue_id)); | |||||
diesel::joinable!(paragraphs -> issues (post_id)); | |||||
diesel::allow_tables_to_appear_in_same_query!( | |||||
comment_votes, | |||||
comments, | |||||
issue_votes, | |||||
issues, | |||||
paragraphs, | |||||
sessions, | |||||
); |