Development

Full Stack + AI Development Program

A full-stack feature, plus a careful place for an AI step inside it.

★★★★★4.8 · Based on 48 learners160 lessons · 40 hr

Full Stack + AI Development Program combines a full-stack feature with one generative step that has a boundary. You will build the ordinary path first — screen, API, and stored data — then add an AI assist that a person can accept or discard. The course assumes web development experience.

Course syllabus

  1. 01. A note you can save

    • The feature without AI

      Create a note with a title and a body, and read it back from stored data.

      15 min
    • The screens in this half

      A list, a create form, and a page for one note.

      17 min
    • The routes in this half

      GET the list, POST a note, and GET one by id.

      13 min
    • The fields in this half

      Title, body, and createdAt, with no summary yet.

      16 min
    • Done means a refresh still shows it

      The note is on the list because it was stored.

      18 min
    • What this half does not include

      No model call, no generated text, and no provider key.

      14 min
    • Accounts can wait

      The create-and-read path cannot wait.

      18 min
    • The path in one line

      Form, POST, document, GET, screen.

      12 min
  2. 02. Screens for create and read

    • A form with title and body

      Both are controlled inputs.

      17 min
    • Submit posts JSON

      The handler sends the fields to POST /notes and waits.

      15 min
    • The list fetches on load

      GET /notes fills an array in state.

      16 min
    • The list shows the title and a short start of the body

      The full body waits on the detail page.

      13 min
    • The id from the server is the link

      The list does not invent a key.

      15 min
    • The detail page loads that id

      It shows the stored title and body.

      17 min
    • The empty list has a sentence

      No notes yet is a state you wrote on purpose.

      13 min
    • These screens have no model button

      Create and read are finished before any draft exists.

      16 min
  3. 03. The notes API

    • The server parses JSON

      A JSON body comes in, and JSON goes out.

      18 min
    • POST /notes inserts one document

      It returns that document with status 201.

      14 min
    • GET /notes returns an array

      Newest first, from the collection.

      18 min
    • GET /notes/:id returns one note or 404

      A missing document is not an empty object.

      12 min
    • The three handlers live in one router

      List, create, and read, attached together.

      17 min
    • Create and read with curl first

      The API works before you trust the form.

      15 min
    • Status codes for this API

      201 for create, 200 for reads, 400 for a bad body, and 404 for a missing note.

      16 min
    • POST does not call another service

      It validates and inserts, and that is the whole handler.

      13 min
  4. 04. Documents in the collection

    • The database URI is read on the server

      It comes from the API environment, not from the browser.

      15 min
    • One collection, one shape

      Title, body, and createdAt.

      17 min
    • Insert only the checked fields

      Plus the time the server sets.

      13 min
    • Read the title back in the shell

      The document matches the POST.

      16 min
    • The URL id is the ObjectId as text

      The detail route uses that value.

      18 min
    • A value that is not an ObjectId is 400

      It fails before a lookup, and the error is JSON.

      14 min
    • Sort newest first

      createdAt descending, so the note you just saved is at the top.

      18 min
    • This document has no summary field

      You add that only in the later half.

      12 min
  5. 05. Validation and error text

    • The title has to be trimmed text

      Empty and over the limit both fail.

      17 min
    • The body has to be non-empty text

      A note with no body is not stored.

      15 min
    • 400 names the field that failed

      The response says title or body.

      16 min
    • The form shows that server message

      It appears by the field, from the response body.

      13 min
    • A dropped network call keeps the typed text

      The person does not lose the note because the request failed.

      15 min
    • The detail page explains a 404

      This note does not exist.

      17 min
    • A 500 on screen is generic

      The server log keeps the stack.

      13 min
    • A hand-built request still hits the check

      Skipping the form does not skip validation.

      16 min
  6. 06. Prove the plain path

    • Create a note and refresh the list

      The row comes from GET, not from form state.

      18 min
    • Open it from the list

      The body matches what you typed.

      14 min
    • A blank title inserts nothing

      The collection does not gain a document.

      18 min
    • A bad id does not leak a cast error

      The client gets 400 JSON, not a library page.

      12 min
    • Search the bundle for the database URI

      It is absent.

      17 min
    • Name the files in this half

      Router, database helper, list, form, and detail.

      15 min
    • Demo create and read with the model code absent

      The path still makes sense if that file does not exist.

      16 min
    • Stop before you add a side effect to insert

      The next work is a new route, not a hidden call inside POST.

      13 min
  7. 07. Where a draft is allowed

    • Where an AI step is allowed

      After a note exists, a person may ask for a one-sentence draft summary.

      15 min
    • POST /notes still does not call a model

      Saving stays a plain insert.

      17 min
    • A button on the detail page

      Suggest a summary, and it is optional.

      13 min
    • The server reads the stored body

      The browser does not get to replace the source of the draft.

      16 min
    • The model result is a draft

      It is shown to the person, and it is not written yet.

      18 min
    • The draft may only compress the body

      The fixed instructions say not to add claims.

      14 min
    • A person is the step after the draft

      Nothing is saved until they accept or edit.

      18 min
    • No chat box and no second model

      This product has one generative step.

      12 min
  8. 08. The provider key

    • The key authorizes the provider

      It is a secret for the outgoing call.

      17 min
    • The API process reads it from the environment

      A variable on the server, present at startup.

      15 min
    • The React bundle must not contain the key

      No client env prefix, and no prop that carries it.

      16 min
    • The sample env file has the name only

      The value stays off the repository.

      13 min
    • The browser calls your draft route

      POST /notes/:id/summary-draft hits the API you wrote.

      15 min
    • The server attaches the key on the way out

      The provider request is built on the server.

      17 min
    • A missing key is a generic 500

      The log says the variable is unset, and the page does not.

      13 min
    • Rotation changes the server env

      The client never knew the old value or the new one.

      16 min
  9. 09. The server calls the model

    • Calling a model from the server

      A function takes the stored body and returns text, or fails.

      18 min
    • The prompt lives in that function

      One sentence, only what the body says, and no extra claims.

      14 min
    • The body is passed as source text

      It is data for the summary, not a new set of instructions.

      18 min
    • The call has a timeout

      A millisecond limit, and past that the function fails.

      12 min
    • A result that is not text is a failure

      You do not guess a summary out of an unexpected shape.

      17 min
    • Do not log the outgoing key

      Log the note id and the outcome, not the authorization header.

      15 min
    • The button never calls the provider

      React only hits your route.

      16 min
    • 200 returns a draft and leaves the note alone

      The document is unchanged until a later save.

      13 min
  10. 10. An unsaved draft on the page

    • The button enters a loading state

      The person can see that the draft request is running.

      15 min
    • Show the draft in its own box

      Separate from the saved title and body.

      17 min
    • The stored note does not change when a draft arrives

      Title and body stay as they were.

      13 min
    • Three actions under the draft

      Accept, edit, and discard.

      16 min
    • Discard closes the box

      No write, and the document stays as it was.

      18 min
    • Edit copies the draft into a field

      The person changes the words before any save.

      14 min
    • Accept and edit use a save route

      They do not reuse the model route.

      18 min
    • Ask again and the unsaved box updates

      A newer draft replaces the old one, and it still does not write.

      12 min
  11. 11. Saving only confirmed text

    • Accept, edit, or discard

      Accept stores the draft, edit stores the revision, and discard stores nothing.

      17 min
    • PATCH /notes/:id/summary writes the text

      The field is set from the words the person confirmed.

      15 min
    • The summary is checked like any other field

      Plain text, under a length cap.

      16 min
    • An empty summary is a real value

      Clearing it stores an empty string on purpose.

      13 min
    • The draft route never writes

      It only returns a draft.

      15 min
    • The list shows a summary only after it is stored

      An unsaved box does not appear as data.

      17 min
    • Reload shows a summary that was patched

      It is on the document, not only in the tab.

      13 min
    • Discard, reload, and the summary is absent

      Memory in the page was not a save.

      16 min
  12. 12. Timeouts and bad model output

    • Timeouts and bad output

      The call can hang, return junk, or add facts that are not in the note.

      18 min
    • A timeout becomes a sentence on the page

      The draft took too long, the person may try again, and the note is unchanged.

      14 min
    • A provider error becomes a 502

      Your route says the draft failed, in a short sentence.

      18 min
    • Empty model text is a failure

      You do not offer a blank draft as a success.

      12 min
    • Pick one rule for a draft that is not one sentence

      Show it for review, or reject it, and then keep that rule.

      17 min
    • Tell the person to compare the draft to the body

      Extra facts are their call to delete, and save still waits.

      15 min
    • Retry once at most

      Then stop and show the error.

      16 min
    • A failed draft does not block GET

      The note page still loads.

      13 min
  13. 13. Access, payment, and untrusted text

    • The model does not decide access

      Your route decides who can open the note, before any model call.

      15 min
    • The model does not decide payment

      A price, a refund, or a plan is not an output you obey.

      17 min
    • Do not ask the model who is allowed

      Permission is a query you wrote, not a prompt.

      13 min
    • A missing note is 404 before the call

      You load the document first, and you skip the model if it is absent.

      16 min
    • Create and read work if the button is never used

      The generative step is optional.

      18 min
    • A flag can turn off only the draft route

      CRUD stays up, and the draft route returns 404.

      14 min
    • Render the draft as text

      Not as HTML.

      18 min
    • Do not execute the draft

      It is words to read, not an instruction to the server.

      11 min
  14. 14. The summary field

    • Add summary as a string

      Default empty, on the note document.

      16 min
    • Older notes still load

      A missing summary reads as empty.

      14 min
    • PATCH enforces a maximum length

      A paste cannot store an unbounded string.

      15 min
    • PATCH does not call the model

      It stores the checked string it was given.

      12 min
    • The read rule is the PATCH rule

      Whoever may open the note may update its summary, and the model is not in that rule.

      14 min
    • Label the saved summary on the page

      Under the body, as the summary, not as the body.

      16 min
    • The box says unsaved until PATCH succeeds

      The person can tell draft from stored text.

      12 min
    • No stored summary means no summary block

      The page simply omits it.

      15 min
  15. 15. Screen states for the draft

    • Idle is the button and no box

      Nothing has been requested.

      18 min
    • Loading disables the button

      A line says the draft is in progress.

      13 min
    • A ready draft shows the three actions

      The text is visible, and it is not saved yet.

      17 min
    • A save in flight does not send twice

      Accept or edit stays disabled until the PATCH returns.

      11 min
    • The summary block updates from the PATCH body

      The page uses the stored value, not a guess.

      16 min
    • A failed draft shows the error line

      The body of the note is untouched.

      14 min
    • Edit mode is a textarea prefilled with the draft

      Save sends that text to PATCH.

      15 min
    • Discard does not call PATCH

      The box closes and the document is the same.

      12 min
  16. 16. Logs that omit the key

    • Log the note id and the outcome

      Started, succeeded, timed out, or provider error.

      14 min
    • Never log the key

      Including headers on the outgoing request.

      16 min
    • Log a length instead of the whole body

      The note may be private, and the size is enough.

      12 min
    • A draft failure is not a create failure

      The log line names the draft route.

      15 min
    • Put one request id on the draft call

      You can find that timeout later.

      18 min
    • The browser gets the short error

      The log can hold more, and the page does not.

      13 min
    • Read one failed draft in the log

      Say whether it timed out or the provider failed.

      17 min
    • A stack that prints the key is a bug

      You change the logging so the secret is not in the trace.

      11 min
  17. 17. Limits on the draft route

    • Refuse a body over the draft limit

      The route stops before the model call.

      16 min
    • Cap the summary on PATCH

      The same class of limit, on the stored field.

      14 min
    • Limit how often the draft route may run

      A small number per minute, so a loop cannot keep calling.

      15 min
    • POST /notes is not under that same tight cap

      Saving a note stays the ordinary path.

      12 min
    • The timeout is one named constant

      The call uses that value, and not a second copy.

      14 min
    • The prompt is one function

      The route does not carry a second copy of the instructions.

      16 min
    • The cap is there because calls cost money

      You can say why, without putting a price on the screen.

      12 min
    • The person sees too long or too many tries

      A clear refusal, not a generic crash.

      15 min
  18. 18. Walk both paths

    • Create is form, POST, document, list

      You can point at each hop.

      18 min
    • Read is list, click, GET, body

      The page shows the stored note.

      13 min
    • Draft is button, server read, model, page

      The key stays on the server in that hop.

      17 min
    • Accept is PATCH, then a reload that still shows it

      The summary was written.

      11 min
    • Discard is no PATCH

      A reload shows no summary.

      16 min
    • A timeout leaves the stored note as it was

      The page says the draft failed.

      14 min
    • Say where the key is

      The server environment, and not the client bundle.

      15 min
    • Two paths, two sentences

      Saving a note never calls a model, and a summary is stored only after a person confirms it.

      12 min
  19. 19. Files in order

    • Server entry and its environment

      Port, database URI, and the model key.

      14 min
    • The notes router

      List, create, read, summary draft, and summary patch.

      16 min
    • The validation module

      Title, body, and summary.

      12 min
    • The model function

      Prompt, timeout, and a string or a failure.

      15 min
    • The list and the form import no model

      Those screens only talk to the plain notes API.

      18 min
    • The detail screen owns the draft actions

      Fetch, the button, accept, edit, discard, and the summary block.

      13 min
    • Nothing in the client bundle imports the key

      You can search and show that it is absent.

      17 min
    • Remove the model function and create still works

      Read still works too.

      11 min
  20. 20. Explain the two paths

    • Explaining the system

      A note is stored by an ordinary API, and a summary is stored only after a person confirms it.

      16 min
    • How you know the key is server-side

      The client calls your route, and the bundle does not contain the secret.

      14 min
    • What the model is allowed to do

      Offer one sentence, and not save it, and not grant access.

      15 min
    • What the person must do

      Accept, edit, or discard before any summary exists on the document.

      12 min
    • How you explain a timeout

      The note stays, and the screen says the draft failed.

      14 min
    • How you explain bad output

      Untrusted text, compared with the body, and never executed.

      16 min
    • Access and payment in this system

      Neither one is a model decision.

      12 min
    • The order of a demo

      Create and read, then a draft, then a discard.

      15 min

Lecture videos stay with the course. Playback for enrolled students will open once payments are available. Video links are not published on this page.