diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c7e834
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.env
+n39env
+.vscode
\ No newline at end of file
diff --git a/createMR.py b/createMR.py
new file mode 100644
index 0000000..7026c71
--- /dev/null
+++ b/createMR.py
@@ -0,0 +1,55 @@
+import os
+import json
+import argparse
+from git import Repo
+from pyforgejo import AuthenticatedClient
+from dotenv import load_dotenv
+from pyforgejo.api.issue import issue_list_issues
+from pyforgejo.api.repository import repo_create_branch, repo_create_pull_request
+from pyforgejo.models import CreateBranchRepoOption, CreatePullRequestOption
+
+load_dotenv()
+
+parser = argparse.ArgumentParser(description="")
+parser.add_argument("-i", "--issue")
+args = parser.parse_args()
+
+FORJEGO_ACCESS_TOKEN = os.getenv("FORJEGO_ACCESS_TOKEN")
+OWNER = os.getenv("OWNER")
+USER = os.getenv("USER")
+REPO = os.getenv("REPO")
+
+client = AuthenticatedClient(
+    base_url="https://git.n39.eu/api/v1/", token=FORJEGO_ACCESS_TOKEN
+)
+
+issues = json.loads(issue_list_issues.sync_detailed(OWNER, REPO, client=client).content)
+
+
+def filterIssues(issue):
+    return args.issue in issue["title"]
+
+
+issues = list(filter(filterIssues, issues))
+
+branchName = issues[0]["title"].replace(" ", "-")
+
+if len(issues) > 1:
+    raise ValueError("found more than one ticket")
+if len(issues) == 0:
+    raise ValueError("found more than one ticket")
+else:
+    repo_create_branch.sync_detailed(
+        OWNER, REPO, body=CreateBranchRepoOption(branchName, "main"), client=client
+    )
+    res = json.loads(
+        repo_create_pull_request.sync_detailed(
+            OWNER,
+            REPO,
+            body=CreatePullRequestOption(
+                base="main", head=branchName, title="merge-" + branchName
+            ),
+            client=client,
+        ).content
+    )
+    print(res)
diff --git a/frontend/.gitignore b/frontend/.gitignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/frontend/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/frontend/src/shared/components/modals/BookModal.tsx b/frontend/src/shared/components/modals/BookModal.tsx
index fb852c1..5c086b6 100644
--- a/frontend/src/shared/components/modals/BookModal.tsx
+++ b/frontend/src/shared/components/modals/BookModal.tsx
@@ -29,7 +29,20 @@ export const BookModal = ({
   }, [book, reset]);
 
   const { scannerError, setScannerRef } = useScanner({
-    onDetected: (result) => {
+    onDetected: async (result) => {
+      const googleBooks = await (
+        await fetch(
+          "https://www.googleapis.com/books/v1/volumes?q=isbn:" + result
+        )
+      ).json();
+      if ("items" in googleBooks) {
+        console.log(googleBooks);
+        setValue(
+          "published",
+          googleBooks.items[0].volumeInfo.publishedDate.substring(0, 4)
+        );
+        setValue("title", googleBooks.items[0].volumeInfo.title);
+      }
       setValue("isbn", result);
       setShowScanner(false);
     },
@@ -38,6 +51,7 @@ export const BookModal = ({
   const values = useWatch({ control });
 
   const [submitError, setSubmitError] = useState<string | undefined>();
+
   const onSubmit = useCallback(
     async (data: Partial<BookForm>) => {
       setSubmitError(undefined);
@@ -89,7 +103,7 @@ export const BookModal = ({
       <ModalHeader
         onClose={onClose}
         title={`${!!book ? "Edit" : "Add new"} Book`}
-        icon={<ImBook size={50} className="ml-0 mr-auto" />}
+        icon={<ImBook size={50} className='ml-0 mr-auto' />}
       />
       <Modal.Body
         style={{
@@ -100,18 +114,18 @@ export const BookModal = ({
       >
         {!showScanner && (
           <Form
-            className="mb-2"
+            className='mb-2'
             onSubmit={(ev) => {
               ev.preventDefault();
               onSubmit(values);
             }}
           >
-            <Form.Group as={Row} className="mb-2">
-              <Col sm="2">
+            <Form.Group as={Row} className='mb-2'>
+              <Col sm='2'>
                 <Form.Label>ISBN</Form.Label>
               </Col>
-              <Col className="d-flex flex-column">
-                <div className="d-flex">
+              <Col className='d-flex flex-column'>
+                <div className='d-flex'>
                   <Form.Control
                     {...register("isbn", { required: true, maxLength: 360 })}
                     isInvalid={!!formState.errors.isbn}
@@ -126,7 +140,7 @@ export const BookModal = ({
                       color: "black",
                       border: "2px solid black",
                     }}
-                    className="mr-2 pt-0"
+                    className='mr-2 pt-0'
                     disabled={showScanner}
                     onClick={() => setShowScanner(true)}
                   >
@@ -135,7 +149,7 @@ export const BookModal = ({
                 </div>
                 <Form.Control.Feedback
                   style={{ display: !formState.errors.isbn ? "none" : "block" }}
-                  type="invalid"
+                  type='invalid'
                 >
                   {!formState.errors.isbn
                     ? "ISBN is required"
@@ -143,8 +157,8 @@ export const BookModal = ({
                 </Form.Control.Feedback>
               </Col>
             </Form.Group>
-            <Form.Group as={Row} className="mb-2">
-              <Col sm="2">
+            <Form.Group as={Row} className='mb-2'>
+              <Col sm='2'>
                 <Form.Label>Title</Form.Label>
               </Col>
               <Col>
@@ -153,15 +167,15 @@ export const BookModal = ({
                   isInvalid={!!formState.errors.title}
                 />
 
-                <Form.Control.Feedback type="invalid">
+                <Form.Control.Feedback type='invalid'>
                   {!values.title
                     ? "Title is required"
                     : formState.errors.title?.message}
                 </Form.Control.Feedback>
               </Col>
             </Form.Group>
-            <Form.Group as={Row} className="mb-2">
-              <Col sm="2">
+            <Form.Group as={Row} className='mb-2'>
+              <Col sm='2'>
                 <Form.Label>Year published</Form.Label>
               </Col>
               <Col>
@@ -187,15 +201,15 @@ export const BookModal = ({
                   isInvalid={!!formState.errors.published}
                 />
 
-                <Form.Control.Feedback type="invalid">
+                <Form.Control.Feedback type='invalid'>
                   {!values.published
                     ? "Year published is required"
                     : formState.errors.published?.message}
                 </Form.Control.Feedback>
               </Col>
             </Form.Group>
-            <Form.Group as={Row} className="mb-2">
-              <Col sm="2">
+            <Form.Group as={Row} className='mb-2'>
+              <Col sm='2'>
                 <Form.Label>Shelf</Form.Label>
               </Col>
               <Col>
@@ -205,21 +219,21 @@ export const BookModal = ({
                 >
                   {Object.keys(bookShelfs).map((key) => (
                     <option
-                      key="key"
+                      key='key'
                       value={bookShelfs[key as keyof typeof bookShelfs]}
                     >
                       {key}
                     </option>
                   ))}
                 </Form.Select>
-                <Form.Control.Feedback type="invalid">
+                <Form.Control.Feedback type='invalid'>
                   {!values.shelf
                     ? "Shelf is required"
                     : formState.errors.shelf?.message}
                 </Form.Control.Feedback>
               </Col>
             </Form.Group>
-            <div className="d-flex mx-auto mb-auto mt-2 w-100">
+            <div className='d-flex mx-auto mb-auto mt-2 w-100'>
               <Button
                 style={{
                   borderRadius: "5px",
@@ -238,12 +252,12 @@ export const BookModal = ({
         )}
         {showScanner && (
           <div
-            className="w-100 overflow-hidden"
+            className='w-100 overflow-hidden'
             ref={(ref) => setScannerRef(ref)}
             style={{ position: "relative", height: "25vh" }}
           >
             <canvas
-              className="drawingBuffer w-100 position-absolute"
+              className='drawingBuffer w-100 position-absolute'
               style={{
                 height: "100%",
                 border: "2px solid black",
@@ -258,7 +272,7 @@ export const BookModal = ({
           </p>
         ) : null}
         {!!submitError && (
-          <Form.Control.Feedback style={{ display: "block" }} type="invalid">
+          <Form.Control.Feedback style={{ display: "block" }} type='invalid'>
             {submitError}
           </Form.Control.Feedback>
         )}
diff --git a/issues b/issues
new file mode 100644
index 0000000..7bb88ed
--- /dev/null
+++ b/issues
@@ -0,0 +1 @@
+[{"id":844,"url":"https://git.n39.eu/api/v1/repos/0Ry5/n39librarian/issues/5","html_url":"https://git.n39.eu/0Ry5/n39librarian/issues/5","number":5,"user":{"id":118,"login":"0Ry5","login_name":"","full_name":"","email":"0ry5@git.n39.eu","avatar_url":"https://git.n39.eu/avatar/b3977e6b4b95a3a537127207119712a2","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2024-09-09T20:35:12+02:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"0Ry5"},"original_author":"","original_author_id":0,"title":"checkout modal can be submitted if its invalid","body":"","ref":"","assets":[],"labels":[],"milestone":null,"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":0,"created_at":"2024-09-13T14:25:22+02:00","updated_at":"2024-09-13T14:25:22+02:00","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":65,"name":"n39librarian","owner":"0Ry5","full_name":"0Ry5/n39librarian"},"pin_order":0},{"id":843,"url":"https://git.n39.eu/api/v1/repos/0Ry5/n39librarian/issues/4","html_url":"https://git.n39.eu/0Ry5/n39librarian/issues/4","number":4,"user":{"id":118,"login":"0Ry5","login_name":"","full_name":"","email":"0ry5@git.n39.eu","avatar_url":"https://git.n39.eu/avatar/b3977e6b4b95a3a537127207119712a2","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2024-09-09T20:35:12+02:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"0Ry5"},"original_author":"","original_author_id":0,"title":"undefined should not be a valid input for the checkout modal","body":"","ref":"","assets":[],"labels":[],"milestone":null,"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":0,"created_at":"2024-09-13T14:25:07+02:00","updated_at":"2024-09-13T14:25:07+02:00","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":65,"name":"n39librarian","owner":"0Ry5","full_name":"0Ry5/n39librarian"},"pin_order":0},{"id":839,"url":"https://git.n39.eu/api/v1/repos/0Ry5/n39librarian/issues/3","html_url":"https://git.n39.eu/0Ry5/n39librarian/issues/3","number":3,"user":{"id":118,"login":"0Ry5","login_name":"","full_name":"","email":"0ry5@git.n39.eu","avatar_url":"https://git.n39.eu/avatar/b3977e6b4b95a3a537127207119712a2","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2024-09-09T20:35:12+02:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"0Ry5"},"original_author":"","original_author_id":0,"title":"add unit tests","body":"","ref":"","assets":[],"labels":[],"milestone":null,"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":0,"created_at":"2024-09-09T20:49:52+02:00","updated_at":"2024-09-09T20:49:52+02:00","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":65,"name":"n39librarian","owner":"0Ry5","full_name":"0Ry5/n39librarian"},"pin_order":0},{"id":838,"url":"https://git.n39.eu/api/v1/repos/0Ry5/n39librarian/issues/2","html_url":"https://git.n39.eu/0Ry5/n39librarian/issues/2","number":2,"user":{"id":118,"login":"0Ry5","login_name":"","full_name":"","email":"0ry5@git.n39.eu","avatar_url":"https://git.n39.eu/avatar/b3977e6b4b95a3a537127207119712a2","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2024-09-09T20:35:12+02:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"0Ry5"},"original_author":"","original_author_id":0,"title":"try google-books api for book identification by isbn","body":"https://www.npmjs.com/package/@googleapis/books\r\n\r\nadd to CreateBookModal","ref":"","assets":[],"labels":[],"milestone":null,"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":0,"created_at":"2024-09-09T20:49:15+02:00","updated_at":"2024-09-09T20:49:15+02:00","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":65,"name":"n39librarian","owner":"0Ry5","full_name":"0Ry5/n39librarian"},"pin_order":0},{"id":837,"url":"https://git.n39.eu/api/v1/repos/0Ry5/n39librarian/issues/1","html_url":"https://git.n39.eu/0Ry5/n39librarian/issues/1","number":1,"user":{"id":118,"login":"0Ry5","login_name":"","full_name":"","email":"0ry5@git.n39.eu","avatar_url":"https://git.n39.eu/avatar/b3977e6b4b95a3a537127207119712a2","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2024-09-09T20:35:12+02:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"0Ry5"},"original_author":"","original_author_id":0,"title":"Darkmode","body":"","ref":"","assets":[],"labels":[],"milestone":null,"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":0,"created_at":"2024-09-09T20:48:27+02:00","updated_at":"2024-09-09T20:48:27+02:00","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":65,"name":"n39librarian","owner":"0Ry5","full_name":"0Ry5/n39librarian"},"pin_order":0}]
diff --git a/middleware/.gitignore b/middleware/.gitignore
new file mode 100644
index 0000000..db4c6d9
--- /dev/null
+++ b/middleware/.gitignore
@@ -0,0 +1,2 @@
+dist
+node_modules
\ No newline at end of file