This is a first stab at adding iterations and user stories to trac. AgileTrac1? is an attempt to do the same thing by replicating the ticket system but for user stories.

This 2nd version is focused on doing the simplest thing that is useful. For this to be most useful we would probably need to add a Size field to tickets, otherwise we won't be able to have a uniform Roadmap page. In this approach we are basically doing two things:

  • User Stories are a 'type' of ticket
  • User Stories have their own default view, that is, the User Story templates will be different from the general ticket templates.

Building and Installing AgileTrac2



  • Postgresql (8.3) as the database for ease of testing with pgAdminIII


  • Create an experimental trac environment so that we can install the plugin and have a look at it.
    • You will have to decide how you will serve your trac instance, either by using tracd or apache.
    • You will also need to add at least one administrative user.
  • Change directory to the location agiletrac2 is checked out to then as root run
    • python develop

  • This will add a link to the site-packages folder of your python install. This means it is possible to develop the plugin and make changes without having to constantly re-install the plugin. The server serving trac may need to be restarted though.

Basic Schema

tables = [

    Table('iteration', key = 'id')[
        Column('id', auto_increment = True),
        Column('time', type='int'),
        Column('changetime', type='int'),
        Column('start_date', type='int'),
        Column('end_date', type='int'),
        Column('planning', type='int'),
        Column('evaluation', type='int'),

    Table('userstory', key = 'id')[
        Column('id', auto_increment = True),
        Column('time', type='int'),
        Column('changetime', type='int'),
        Column('started_in_iteration', type='int'),
        Column('test_complete_in_iteration', type='int'),
        Column('doc_complete_in_iteration', type='int'),
        Column('acceptance_complete_in_iteration', type='int'),
    Table('userstory_change', key=('userstory', 'time', 'field'))[
        Column('userstory', type='int'),
        Column('time', type='int'),

The goal here then is to use the milestone from the ticket system for user stories.

If we add a size field to tickets then we can update the Roadmap page to use both tickets and user stories. We can use colours to help show staged progress of user stories. In other words Green will only be for Closed tickets and Done user stories. We can use orange to Test Complete or Doc Complete user stories that are not yet Done. The total 'size' of the milestone will be the summation of the total points of all stories and tickets in the milestone. Tickets and User Stories with an undetermined size should only placed in a placeholder Undefined milestone. In an ideal world we would enforce this but lacking time it would be probably sufficient to simply record the proper etiquette. Taking this approach makes it easy for us to simply assign a size of 0 (or other sensible default) to undefined tickets and stories for the purpose of generating the Roadmap page. In this case only the undefined milestone will be skewed. We could also hard code to ignore the last defined milestone or a milestone called undefined.

Status of User Stories

At the moment it is likely that the Status of a user story will take one of three states

  • Not Done (active)
  • Done (test_complete or acceptance_complete)
  • Split

It might also make sense for the Status to be largely inferred from the completion state. In that case the Status could only take 2 states which would then be a manual selection. The to states would be,

  • Active
  • Split

This could be referred to as split_status as it is above.

The roadmap state would be calculated based on the size stories that are not split and tickets for a given milestone.


Iterations should be simple and at a basic level only need to consist of a,

  • description
  • start_date
  • end_date
  • user_stories

By introducing a shorthand reference for iterations we could use iteration:xxx to refer to an iteration on a wiki page. This would allow use to not worry about planning and evaluation pages. These would simply be appropriately named wiki pages. In the schema shown above we have an id field for a planning and evaluation. In the future this could be used to identify a specific planning or evaluation page that would be essentially a wiki page but allow a more intuitive interface for planning and evaluating. For example, a table of user stories for the current iteration could be automatically displayed. The completion state of the stories could be displayed based on the completed_in_iteration field. In other words a story could be marked not complete on the planning page while also appearing as complete on the evaluation page.

Actually after some thought evaluation and planning would not be id's but wiki page names. However, after further thought it would probably make sense then to have a

  attribute_name (for example "planning")
  summary (for example "This is a planning page for iteration XXX")
  wiki_page (for example, "iteration_XXX_planning_page")
  order (for example, "0" - the first part of an iteration)

This would allow the interface of iterations to be customised with additional fields as appropriate. The downside to this is that the iteration pages would live in the Wiki table on the database. This may not be a problem though.

Another alternative would simply be to add planning and evaluation text fields.

Points Per Iteration

It is unclear if we need to store the points completed for an iteration as this can be calculated. This would be used to calculate the Roadmap page and could also be displayed both on the evaluation page and on an Iterations page, which would be somewhat like the Roadmap page.

Raising Tickets against User Stories

The original thought here was to be able to raise tickets against user stories. However the same effect can be achieved by making a user story 'depend' on (or be blocked by) a ticket. This simplifies things somewhat and allows a uniform way of displaying the relationship between tickets and stories.

User Stories as tickets

An observation was made for iterations that suggested using references to wiki pages for some descriptive parts of the iteration. This general principle could be used to allow the description of a ticket to be a reference to a wiki page. Indeed this could be determined by the type of the ticket. In other words if the ticket type was user_story it might mean that we have three wiki pages associated with it, a pre-iteration, iteration development and post-iteration.

For this to work we would probably need to add a source column to the wiki table. This would contribute to the uniqueness of the wiki row and therefore prevent clashes due to same named pages of a different source.