- modules: document (using OODoc), test, release
- metrics: use Devel::DProf and Devel::Cover everywhere
- Class::MethodMaker
  - fix Build.PL/test bug in 2.05
  - convert everything to v2
  - make it work with OODoc
- Registry::Core
  - has mock objects for network things
  - comes with everything you need to run an EPP registry: an EPP-enabled
    mod_perl 2, the EPP schemata etc.
  - also comes with a whois, nscheck, statistical software and other auxiliary
    applications
- distributions that aren't released to CPAN (Class::MethodMaker::Util in v1
  and all the registry code) is still released, in various versions, to a local
  CPAN which can be accessed from the cpan shell using "o conf urllist push
  file:///...".
- all distributions are based on Build.PL, so they can specify which versions
  of prerequisites to use. This means that, for example, Registry::NICAT v2.01
  might require Registry::Core v1.14, so if we update the Registry::Core with
  something that breaks the API we can release it as v1.15 without interfering
  with Registry::NICAT - just put "1.14, != 1.15" in the appropriate
  prerequisite declaration in Registry::NICAT's Build.PL.
- when installing a specific registry software, such as Registry::NICAT, you
  just have to "install Registry::NICAT" from the cpan shell - the dependencies
  are taken care of.
- separated concerns are easier to understand, easier to test and easier to
  debug.

- Logging: Log::Dispatch-like

- test service methods

- Perltidy {{{1

  - tell it about Error's try/catch/with/finally/...
  - option to convert from dos to unix
  - s/([\]}])->([\[{])/$1$2/g   # hash/array reference chaining
  - s/(->\w+)\(\)/$1/g;         # remove empty arg parens on method calls
  - s/\s+$//;                   # remove trailing whitespace
  - s/\t/    /g;                # expand tabs
  - inline perltidy instructions, like how to align lines:

        # tidy: Align =>

- Transition to payload objects {{{1

  - Data::Conveyor::Test::Class::MethodMaker has to be split into several
    classes, depending on where the accessor generator is defined
    (Class::MethodMaker::Util, for example).

- Check for absolute package names {{{1

    grep -Pr 'Data::Conveyor(::\w+)+\w+->' {bin,lib,t}/*

- Data::Conveyor::Mutex {{{1

  - needs tests
  - ADMINADDR should be a constant
  - individual methods in Data::Conveyor::NICAT::Storage::DBI::Oracle::Mutex
    will have been tested already


- regsh.pl {{{1

  Incorporate the following functionality, then crm those files

  - crm bin/util2003/make_ticket.pl
  - crm bin/util2003/is_person_used.pl
  - crm bin/util2003/set_ticket_stage.pl
  - crm bin/util2003/search-mail.pl

  - separate logic from presentation so the logic can be tested (and possibly
    reused)

  - keep a ~/.regsh_history (a different file can be specified using a
    command-line option) so commands from previous sessions are available

  - redirect output also to a file: output start myfile.txt; output status;
    output stop.

  - Moeglichkeit zum Entfernen eines Fehlers aus einem Ticket (regsh).

  - Moeglichkeit zum Hinzufuegen eines Fehlers zu einem Ticket (regsh). 

  - Moeglichkeit zum 'lautlosen' Canceln eines Tickets (regsh, Achim hat schon
    ein Webinterface angepasst).

  - Anzeige von Personen-, Domain- und Registrardaten aus der regsh.

  - control the reg_dispatch access file. Service methods:

    - enable and disable some or all stages
    - list enabled stages
    - return the list of ticket numbers to ignore
    - remove a ticket number from the list
    - add a ticket number to the list
    - clear the list of ticket numbers

  - clone a ticket

  - edit ticket (using $ENV{EDITOR}; when exited, read back and write ticket)

  - mvs functionality:

    - look for a mail
    - resend a mail (edit using $ENV{EDITOR} in a temp file, change recipients)
      by making an entry into the mvs tables

  - move the core of these methods to their respective classes, e.g.,
    mvs-related commands move to Data::Conveyor::Channel::Mail; others might
    move to Data::Conveyor::Ticket, probably as class methods. Each of these
    methods returns a complex data structure, or possibly some form of
    Data::Conveyor::Service::Response objects. The specific service interface
    (regsh, SOAP etc.) can then decide how to present the response. For
    example, the regsh will print it, transformed by Text::Table, whereas SOAP
    will return it over the connection.

    This design separates logic (methods) from presentation (the service
    interfaces).

  - now that most of the code has gone to various classes (like
    Data::Conveyor::Ticket) and to the storage layer, Data::Conveyor::Shell can
    probably all be kept in one file again; no need to load the commands with
    load_class at the beginning of Data::Conveyor::Shell.

- Miscellaneous {{{1

  - dispatcher: have a list of ticket numbers to ignore from the reg_dispatch
    access file, useful for debugging crashed tickets

- Data::Conveyor::Control::File {{{1

  - when service interfaces change them, the file has to be written back so the
    reg_dispatch.pl can pick up the changes when it re-reads the file. So we
    need file locking (Fcntl).

  - write tests for Data::Conveyor::Control


- Localization {{{1

  - every static string found in the framework is a candidate for localization
    ('...', "...", qw/.../, qq/.../, q/.../ etc.)
  - use Locale::Maketext

- Service interfaces {{{1

  - Data::Conveyor::Monitor: where the activity() service method lives (wraps
    the storage method)

- why are Data::Dumper and Carp being imported into classes (apart from
  Data::Conveyor::Shell and test classes)?  Get rid of it.

- why are we using 'die' and not exceptions? cf. ":grep -Pr 'die\s+\W' lib/*"

- as soon as a stage opens or closes a ticket, $log->info() that so it's seen
  in the scheduler log. In Data::Conveyor::Ticket->open(), or maybe in
  Data::Conveyor::Stage::SingleTicket->main() ?

- consider using a provides/requires-scheme in determining the order of
  transactions in txsel

- use 'foo' instead of qw/foo/: grep -Pr 'qw/\S+/' *

- have more meaningful exceptions instead of
  Error::Hierarchy::Internal::DBI and their subclasses. When using DBI
  code, use a try block in which the dbi code is executed, then in the catch
  block catch Error::Hierarchy::Internal::DBI with { my $E = shift;
  $E->message(sprintf 'meaningful explanation. [%s]', $E->message); throw $E };

- use assert_class where possible for runtime type checking

- autogen error messages in assert_defined etc.: "x expected y, not z". x via
  caller, y is arg to assert_*, z via ref.

- ticket constructors for different ticket types (TT_*)

- replace eval blocks with proper try/catch blocks

Documentation

- documentation {{{1
  - OODoc documentation for each module
  - Data::Conveyor::MethodMaker: import() to store definition in calling class,
    then subclass OODoc::Parser::Markov and extend with MethodMaker method
    directives
  - document each class
  - write overview (Data::Conveyor::Overview, pod-only)

- Version tags {{{1

  - make sure all modules have a $VERSION and an CVS-Id tag. Use the right
    $VERSION numbers in each branch and on the main trunk. Set it to '1.1' in
    the v1_1 branch, and to '1.2' on the trunk.

}}}

Tests

- Miscellaneous {{{1

  - write tests for Data::Conveyor::Service::Methods

  - stress tests

  - test cancel with target cltid is the same as the ticket's cltid

  - refactor tests using YAML::Active::Include

- Metrics {{{1

  - subject the distribution to

    - Devel::TraceCalls
    - Devel::DProf
    - Devel::SmallProf
    - Devel::Size::Report
    - Devel::Coverage
    - DBI_PROFILE

}}}

# vim: fdm=marker
