> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Build a Team PTO Tracker

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero title="Build a Team PTO Tracker" description="Describe your tool and Devin builds, tests, and verifies it end-to-end." prompt="Build an internal PTO tracker for our team under /internal/pto. Employees submit time-off requests with a date range, type (vacation, sick, personal), and optional note. Managers see a queue of pending requests and approve or deny. Calendar view shows who's out, color-coded by type. Dashboard shows every employee's PTO balance (20 days/year). Employees can't exceed their balance or overlap existing PTO. Warn if teammates are already out. Slack notifications on submit and approval/denial via SLACK_WEBHOOK_URL. Use our Next.js app, Prisma ORM, and existing DataTable and Calendar components. Before writing code, outline your plan for review. Write tests for balance calculations, overlap detection, and the approval workflow. Test every page and flow in the browser — submit, approve, deny, check calendar, verify dashboard. Do not open a PR until everything works end-to-end." category="Feature Development" features="" />

<div className="uc-detail-wrapper">
  <Tip>Don't want to set this up manually? Paste a link to this page into a Devin session and ask it to set everything up for you.</Tip>

  <Steps>
    <Step title="(Optional) Scope the codebase with Ask Devin">
      If you already have internal tools in your app, use [Ask Devin](https://app.devin.ai/search?utm_source=docs\&utm_medium=use-case-gallery) to understand the existing patterns before writing your spec. This is especially useful if you want the new tool to match the architecture of what's already there:

      <PromptBlock agent="ada">
        ```txt Scope internal tools architecture theme={null}
        Show me how our existing internal tools are structured:
        1. What pages exist under /internal/ and how are they laid out?
        2. How do internal pages handle auth and role-based access?
        3. Which shared UI components do they use (tables, forms, modals)?
        4. How are database migrations structured in our Prisma schema?
        5. Are there any existing notification patterns (Slack, email)?
        ```
      </PromptBlock>

      Use the answers to fill in your spec with specific file references, component names, and patterns so Devin builds something consistent with your existing tools. You can also start a Devin session directly from Ask Devin, and it will carry over everything it learned as context.
    </Step>

    <Step title="Write a detailed spec">
      Internal tools — PTO trackers, admin panels, data scripts, CLI utilities — are essential but rarely prioritized. They're ideal for Devin because the requirements are well-defined, the audience is your team, and "works correctly" matters more than pixel-perfect design.

      Be specific about what the tool does, what data it stores, and what services it connects to. The more detail you include, the closer the first version matches what you need.

      <PromptBlock>
        ```txt Build a team PTO tracker theme={null}
        Build an internal PTO tracker for our team under /internal/pto.

        ## Features
        - Employees can submit time-off requests with a date range, type
          (vacation, sick, or personal), and an optional note
        - Managers see a queue of pending requests and can approve or deny
          each one
        - A calendar view shows who's out on which days, color-coded by type
        - A dashboard shows every employee's PTO balance: total days,
          used days, remaining days, and pending requests
        - Each employee gets 20 PTO days per year
        - Employees can't request more days than their remaining balance
        - Requests can't overlap with their own existing approved PTO
        - Show a warning (not a block) if teammates are already out during
          the same dates

        ## Notifications
        - Slack notification to the manager when a request is submitted
        - Slack notification to the employee when it's approved or denied
        - Use SLACK_WEBHOOK_URL from env vars

        ## Technical notes
        - Use our existing Next.js app and Prisma ORM
        - Follow the layout pattern in /internal/users
        - Reuse DataTable and Calendar components from src/components/ui/

        ## Planning
        - Before writing code, outline your implementation plan and share
          it with me for review

        ## Testing
        - Write tests for balance calculations, date overlap detection,
          and the approval workflow
        - After implementing, spin up the dev server and test every page
          and flow in the browser — submit a request, approve it, deny one,
          check the calendar, verify dashboard numbers, and test edge cases
          like overlapping dates and exceeding balance
        - Do not open a PR until everything works end-to-end
        ```
      </PromptBlock>

      You can also iterate on your spec using Ask Devin — paste a rough draft and ask it to identify gaps or suggest improvements based on your codebase.
    </Step>

    <Step title="Add credentials">
      Pass any API keys or tokens Devin needs via [Secrets](/product-guides/secrets) — in this case, the Slack webhook URL.

      The simplest approach is to store them as organization secrets before starting the session:

      1. Go to **Settings > Secrets** and add `SLACK_WEBHOOK_URL`
      2. Devin accesses secrets as environment variables, so they never end up hardcoded in your source code.

      <Note>Organization secrets must be added **before** starting the session — they're injected at session start. Alternatively, you can provide secrets during the session using the chat, and Devin will also proactively ask you for any credentials it needs when it encounters missing environment variables.</Note>
    </Step>

    <Step title="Guide the session with slash commands">
      Once the session starts, you can use slash commands to steer Devin's workflow:

      * **`/plan`** — Ask Devin to create a thorough implementation plan before writing any code. Review the plan and suggest changes before it starts building.
      * **`/test`** — Tell Devin to run all tests and verify its work. Use this after each major milestone to catch issues early.
      * **`/review`** — Ask Devin to review its own code for bugs, edge cases, and style issues before opening the PR.

      These commands work at any point during the session — use `/plan` at the start, `/test` after each feature is built, and `/review` before the final PR.
    </Step>

    <Step title="Devin builds it and verifies it works">
      Devin treats internal tools like any production feature — it writes the code, adds tests, and then opens the app in its built-in browser to verify the UI works end-to-end.

      1. **Investigates your codebase** — Finds your `DataTable` and `Calendar` components, reads your Prisma schema, and studies the existing `/internal/` page layout
      2. **Creates the database migration** — Adds `pto_requests` and `pto_balances` tables via Prisma
      3. **Builds the pages** — Request submission form, manager approval queue, calendar view, and balance dashboard under `/internal/pto`
      4. **Integrates Slack** — Sends webhook notifications when requests are submitted and when they're approved or denied
      5. **Writes tests** — Unit tests for PTO balance calculations and date-overlap detection, API tests for the request endpoints, integration tests for the approval workflow
      6. **Opens the app in its browser** — Navigates to every page, submits a test PTO request, approves it from the manager view, verifies the calendar updates, checks the dashboard numbers, and tests edge cases like overlapping dates and exceeding balances
      7. **Opens a PR** — Delivers everything: migration, seed script, application code, tests, and a README section explaining how to use the tool

      Browser verification catches issues that automated tests miss — broken form layouts, a calendar that renders but doesn't respond to clicks, or a submit button that doesn't clear the form after success.
    </Step>

    <Step title="Extend your tool">
      Once the base tool works, add features in follow-up sessions:

      <PromptBlock>
        ```txt Add PTO conflict detection theme={null}
        When an employee submits a PTO request, check if anyone else on their
        team is already out during the same dates. Show a warning in the UI:
        "2 others on your team are out Nov 20-22." Don't block the request,
        just surface the overlap so managers can plan.
        ```
      </PromptBlock>

      <PromptBlock>
        ```txt Build a CSV export for HR theme={null}
        Add a button on the PTO dashboard that exports all approved time off
        for the current quarter as a CSV. Columns: employee name, dates, type,
        days used, remaining balance. HR downloads this monthly for payroll.
        ```
      </PromptBlock>
    </Step>

    <Step title="Review the PR with Devin Review">
      Once Devin opens the PR, use [Devin Review](https://app.devin.ai/review?utm_source=docs\&utm_medium=use-case-gallery) to review the changes. Devin Review has full context of your codebase and can catch bugs, security issues, and style inconsistencies across the diff.
    </Step>
  </Steps>
</div>
