diff --git a/backend/alembic/env.py b/backend/alembic/env.py index ab70110..fb0f5d3 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -57,7 +57,7 @@ def run_migrations_offline() -> None: def do_run_migrations(connection: Connection) -> None: - context.configure(connection=connection, target_metadata=target_metadata) + context.configure(connection=connection, target_metadata=target_metadata, compare_server_default=True, compare_type=True) with context.begin_transaction(): context.run_migrations() diff --git a/backend/alembic/versions/9b7ccd38c01a_test.py b/backend/alembic/versions/9b7ccd38c01a_test.py new file mode 100644 index 0000000..9283922 --- /dev/null +++ b/backend/alembic/versions/9b7ccd38c01a_test.py @@ -0,0 +1,28 @@ +"""test + +Revision ID: 9b7ccd38c01a +Revises: dfb99ba1c75e +Create Date: 2023-01-03 23:30:42.286979 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '9b7ccd38c01a' +down_revision = 'dfb99ba1c75e' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/backend/alembic/versions/b16d4a12f55f_test.py b/backend/alembic/versions/b16d4a12f55f_test.py new file mode 100644 index 0000000..cbc5f50 --- /dev/null +++ b/backend/alembic/versions/b16d4a12f55f_test.py @@ -0,0 +1,28 @@ +"""test + +Revision ID: b16d4a12f55f +Revises: 9b7ccd38c01a +Create Date: 2023-01-03 23:33:23.628323 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'b16d4a12f55f' +down_revision = '9b7ccd38c01a' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/backend/alembic/versions/d4125430c46f_set_server_default.py b/backend/alembic/versions/d4125430c46f_set_server_default.py new file mode 100644 index 0000000..c542873 --- /dev/null +++ b/backend/alembic/versions/d4125430c46f_set_server_default.py @@ -0,0 +1,34 @@ +"""set server default + +Revision ID: d4125430c46f +Revises: e0a3988a875d +Create Date: 2023-01-04 00:16:43.307461 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'd4125430c46f' +down_revision = 'e0a3988a875d' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('notes', 'checked', + existing_type=sa.BOOLEAN(), + server_default='f', + existing_nullable=False) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('notes', 'checked', + existing_type=sa.BOOLEAN(), + server_default=None, + existing_nullable=False) + # ### end Alembic commands ### diff --git a/backend/alembic/versions/e0a3988a875d_test.py b/backend/alembic/versions/e0a3988a875d_test.py new file mode 100644 index 0000000..cb2e952 --- /dev/null +++ b/backend/alembic/versions/e0a3988a875d_test.py @@ -0,0 +1,28 @@ +"""test + +Revision ID: e0a3988a875d +Revises: b16d4a12f55f +Create Date: 2023-01-03 23:43:28.541936 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'e0a3988a875d' +down_revision = 'b16d4a12f55f' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/backend/app/models.py b/backend/app/models.py index b8a839f..19e984a 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -20,7 +20,7 @@ class Note(Base): id = sa.Column(sa.Integer, primary_key=True) title = sa.Column(sa.String, nullable=False) - checked = sa.Column(sa.Boolean, nullable=False, default=False) + checked = sa.Column(sa.Boolean, nullable=False, server_default='f') __all__ = ['engine', 'Base', 'async_session', 'Note'] diff --git a/backend/app/routes.py b/backend/app/routes.py index 5e03c2b..7ddb074 100644 --- a/backend/app/routes.py +++ b/backend/app/routes.py @@ -1,4 +1,4 @@ -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, Response from pydantic import BaseModel from sqlalchemy import select, update, delete from sqlalchemy.ext.asyncio import AsyncSession @@ -16,20 +16,23 @@ async def get_notes(session: AsyncSession = Depends(get_session)): return result.scalars().all() +class NoteResponse(BaseModel): + id: int + title: str + checked: bool + + class NoteCreate(BaseModel): title: str -@router.post("/items/create") +@router.post('/items/create', response_model=NoteResponse) async def create_note(req: NoteCreate, session: AsyncSession = Depends(get_session)): note = Note(title=req.title) session.add(note) await session.commit() - return { - "id": note.id, - "title": note.title, - "checked": note.checked - } + await session.refresh(note) + return NoteResponse(id=note.id, title=note.title, checked=note.checked) class NoteUpdateReq(BaseModel): @@ -38,30 +41,26 @@ class NoteUpdateReq(BaseModel): checked: bool -@router.put("/items/update") +@router.put('/items/update', response_model=NoteResponse) async def update_note(req: NoteUpdateReq, session: AsyncSession = Depends(get_session)): await session.execute( - update(Note).where(Note.id == req.id).values(req.__dict__) + update(Note).where(Note.id == req.id).values(req.dict()) ) await session.commit() - return { - "id": req.id, - "title": req.title, - "checked": req.checked - } + return NoteResponse(**req.dict()) class NoteDeleteReq(BaseModel): id: int -@router.delete("/items/delete") +@router.delete('/items/delete') async def delete_note(req: NoteDeleteReq, session: AsyncSession = Depends(get_session)): await session.execute( delete(Note).where(Note.id == req.id) ) await session.commit() - return 204 + return Response(None, 204) __all__ = ["router"] diff --git a/frontend/src/App.vue b/frontend/src/App.vue index ee987fc..ad5685f 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -4,42 +4,38 @@ import Item from "./components/Item.vue"; import Edit from "./components/Edit.vue"; import config from "./config"; import axios from 'axios' +import INote from "./INote"; + onMounted(async () => { - const response = await axios.get(`${config.apiEndpoint}/items`) + const response = await axios.get(`${config.apiEndpoint}/items`) notes.value = response.data - id = Math.max(...notes.value.map((note: any) => note.id), 0) - currentNote.value.id = id += 1 }) +const notes = ref([]) +const editingNote = ref({id: -1, title: "", checked: false}) -let id; -const notes = ref([]) -const currentNote = ref({id: id += 1, title: "", checked: false}) - -async function processNote(note: any) { +async function updateNote(note: INote) { const index = notes.value.findIndex((item) => item.id === note.id) if (index !== -1) { - await axios.put(`${config.apiEndpoint}/items/update`, note).then((response) => { - notes.value[index] = response.data - }) + const resp = await axios.put(`${config.apiEndpoint}/items/update`, note) + notes.value[index] = resp.data } else { - await axios.post(`${config.apiEndpoint}/items/create`, {title: note.title}).then((response) => { - notes.value.push(response.data) - }) + const resp = await axios.post(`${config.apiEndpoint}/items/create`, {title: note.title}) + notes.value.push(resp.data) } - currentNote.value = {id: id += 1, title: "", checked: false} + editingNote.value = {id: -1, title: "", checked: false} } -async function deleteNote(note: any) { +async function deleteNote(note: INote) { await axios.delete(`${config.apiEndpoint}/items/delete`, {data: {id: note.id}}) notes.value = notes.value.filter((item) => item.id !== note.id) } -async function updateChecked(id: any, checked: boolean) { +async function updateChecked(id: number, checked: boolean) { const index = notes.value.findIndex((item) => item.id === id) if (index !== -1) { notes.value[index].checked = checked @@ -53,15 +49,15 @@ async function updateChecked(id: any, checked: boolean) { diff --git a/frontend/src/INote.ts b/frontend/src/INote.ts new file mode 100644 index 0000000..edbba6d --- /dev/null +++ b/frontend/src/INote.ts @@ -0,0 +1,5 @@ +export default interface INote { + id: number + title: string + checked: boolean +} \ No newline at end of file diff --git a/frontend/src/components/Edit.vue b/frontend/src/components/Edit.vue index 1bc47c5..1e14fa5 100644 --- a/frontend/src/components/Edit.vue +++ b/frontend/src/components/Edit.vue @@ -1,7 +1,9 @@